﻿Imports System
Imports System.Xml
Imports System.Collections.ObjectModel
Imports System.Data
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Windows.Controls
Imports System.IO
Imports System.Xml.Serialization
Imports System.Text

''' <summary>
''' XML Database and Settings Parser
''' Version 2.0
''' </summary>
''' <remarks></remarks>
Public Class FastXML
    Implements IDatabase

#Region "Init"
    Private _directory As String
    Private artikelliste As String
    Private auftragsliste As String
    Private kundenliste As String
    Private kategorieliste As String
    Private companysettings As String
    Private temp As String

    Private xdartikel As Xml.XmlDocument
    Private XmlOrders As Xml.XmlDocument
    Private xdkunden As Xml.XmlDocument
    Private xdkategorien As Xml.XmlDocument
    Private xdglobalsettings As Xml.XmlDocument
    Private xdcompanysettings As Xml.XmlDocument
    Private xdtemp As Xml.XmlDocument

    Private Sub InitializeGlobalSettings()
        Dim path As String = _directory + "\Firma\globalsettings.xml"
        Dim sb As New Text.StringBuilder
        sb.Append(path)
        'if the file doesn't exist, create a blank xml
        If Not IO.File.Exists(path) Then
            Dim fn As New IO.StreamWriter(IO.File.Open(path, IO.FileMode.Create), Text.Encoding.UTF8)
            fn.WriteLine("<?xml version=""1.0"" encoding=""utf-8""?>")
            fn.WriteLine("<Settings>")
            fn.WriteLine("</Settings>")
            fn.Close() 'all done
        End If
    End Sub

    Private Sub InitializeArtikelliste(ByVal path As String)
        Dim sb As New Text.StringBuilder
        sb.Append(path)
        'if the file doesn't exist, create a blank xml
        If Not IO.File.Exists(path) Then
            Dim fn As New IO.StreamWriter(IO.File.Open(path, IO.FileMode.Create), Text.Encoding.UTF8)
            fn.WriteLine("<?xml version=""1.0"" encoding=""utf-8""?>")
            fn.WriteLine("<Artikelliste>")
            fn.WriteLine("</Artikelliste>")
            fn.Close() 'all done
        End If
    End Sub

    Private Sub InitializeTempliste(ByVal path As String)
        Dim sb As New Text.StringBuilder
        sb.Append(path)
        'if the file doesn't exist, create a blank xml
        If Not IO.File.Exists(path) Then
            Dim fn As New IO.StreamWriter(IO.File.Open(path, IO.FileMode.Create), Text.Encoding.UTF8)
            fn.WriteLine("<?xml version=""1.0"" encoding=""utf-8""?>")
            fn.WriteLine("<Temp>")
            fn.WriteLine("</Temp>")
            fn.Close() 'all done
        End If
    End Sub

    Private Sub InitializeAuftragsliste(ByVal path As String)
        Dim sb As New Text.StringBuilder
        sb.Append(path)
        'if the file doesn't exist, create a blank xml
        If Not IO.File.Exists(path) Then
            Dim fn As New IO.StreamWriter(IO.File.Open(path, IO.FileMode.Create), Text.Encoding.UTF8)
            fn.WriteLine("<?xml version=""1.0"" encoding=""utf-8""?>")
            fn.WriteLine("<Auftragsliste>")
            fn.WriteLine("</Auftragsliste>")
            fn.Close() 'all done
        End If
    End Sub

    Private Sub InitializeKundenliste(ByVal path As String)
        Dim sb As New Text.StringBuilder
        sb.Append(path)
        'if the file doesn't exist, create a blank xml
        If Not IO.File.Exists(path) Then
            Dim fn As New IO.StreamWriter(IO.File.Open(path, IO.FileMode.Create), Text.Encoding.UTF8)
            fn.WriteLine("<?xml version=""1.0"" encoding=""utf-8""?>")
            fn.WriteLine("<Kundenliste>")
            fn.WriteLine("</Kundenliste>")
            fn.Close() 'all done
        End If
    End Sub

    Private Sub InitializeKategorieliste(ByVal path As String)
        Dim sb As New Text.StringBuilder
        sb.Append(path)
        'if the file doesn't exist, create a blank xml
        If Not IO.File.Exists(path) Then
            Dim fn As New IO.StreamWriter(IO.File.Open(path, IO.FileMode.Create), Text.Encoding.UTF8)
            fn.WriteLine("<?xml version=""1.0"" encoding=""utf-8""?>")
            fn.WriteLine("<Kategorieliste>")
            fn.WriteLine("  <Category Name=""Alle Kategorien"">")
            fn.WriteLine("  </Category>")
            fn.WriteLine("  <Category Name=""Nebenleistungen"">")
            fn.WriteLine("  </Category>")
            fn.WriteLine("</Kategorieliste>")
            fn.Close() 'all done
        End If
    End Sub

    Private Sub InitializeCompanySettings(ByVal path As String)
        Dim sb As New Text.StringBuilder
        sb.Append(path)
        'if the file doesn't exist, create a blank xml
        If Not IO.File.Exists(path) Then
            Dim fn As New IO.StreamWriter(IO.File.Open(path, IO.FileMode.Create), Text.Encoding.UTF8)
            fn.WriteLine("<?xml version=""1.0"" encoding=""utf-8""?>")
            fn.WriteLine("<company>")
            fn.WriteLine("</company>")
            fn.Close() 'all done
        End If
    End Sub

    Public Sub Connect() Implements IDatabase.Connect
        Try
            '### Normal Loading
            xdglobalsettings = New XmlDocument
            InitializeGlobalSettings()
            xdglobalsettings.Load(_directory + "\Firma\globalsettings.xml")
        Catch ex As Exception
            Dim repairwizard As New DBRepairWizard
            repairwizard.ShowDialog()

            '### Normal Loading
            xdglobalsettings = New XmlDocument
            InitializeGlobalSettings()
            xdglobalsettings.Load(_directory + "\Firma\globalsettings.xml")
        End Try


        If String.IsNullOrEmpty(LastCompany) Then
            _isconnected = True
            RaiseEvent DatabaseConnected(Me)
            Exit Sub

        Else
            artikelliste = _directory + "Firma\" + LastCompany + "\artikelliste.xml"
            auftragsliste = _directory + "Firma\" + LastCompany + "\auftragsliste.xml"
            kundenliste = _directory + "Firma\" + LastCompany + "\kundenliste.xml"
            kategorieliste = _directory + "Firma\" + LastCompany + "\kategorieliste.xml"
            companysettings = _directory + "Firma\" + LastCompany + "\settings.xml"
            temp = _directory + "Firma\" + LastCompany + "\opentemp.xml"

            xdartikel = New XmlDocument
            InitializeArtikelliste(_directory + "Firma\" + LastCompany + "\artikelliste.xml")
            xdartikel.Load(artikelliste)

            XmlOrders = New XmlDocument
            InitializeAuftragsliste(_directory + "Firma\" + LastCompany + "\auftragsliste.xml")
            XmlOrders.Load(auftragsliste)

            xdkunden = New XmlDocument
            InitializeKundenliste(_directory + "Firma\" + LastCompany + "\kundenliste.xml")
            xdkunden.Load(kundenliste)

            xdkategorien = New XmlDocument
            InitializeKategorieliste(_directory + "Firma\" + LastCompany + "\kategorieliste.xml")
            xdkategorien.Load(kategorieliste)

            xdcompanysettings = New XmlDocument
            InitializeCompanySettings(companysettings)
            xdcompanysettings.Load(companysettings)

            xdtemp = New XmlDocument
            InitializeTempliste(temp)
            xdtemp.Load(temp)
        End If
        _isconnected = True
        RaiseEvent DatabaseConnected(Me)
    End Sub

    Public Event DatabaseConnected(source As Object) Implements IDatabase.DatabaseConnected

    Public Event DatabaseNotConnected(source As Object) Implements IDatabase.DatabaseNotConnected

    Private _isconnected As Boolean = False

    Public ReadOnly Property IsConnected As Boolean Implements IDatabase.IsConnected
        Get
            Return _isconnected
        End Get
    End Property
#End Region

    Public Sub New(path As String)
        If String.IsNullOrEmpty(path) Then
            path = System.AppDomain.CurrentDomain.BaseDirectory()
        End If
        If Not Directory.Exists(path + "\Firma") Then
            Directory.CreateDirectory(path + "\Firma")
        End If
        If Not path.EndsWith("\") Then
            _directory = path + "\"
        Else
            _directory = path
        End If
    End Sub

#Region "Reloading"
    Public Sub ReloadGlobalSettings() Implements IDatabase.ReloadGlobalSettings
        xdglobalsettings = New XmlDocument
        xdglobalsettings.Load(_directory + "\Firma\globalsettings.xml")
    End Sub

    Public Sub ReloadCompanySettings() Implements IDatabase.ReloadCompanySettings
        xdcompanysettings = New XmlDocument
        companysettings = _directory + "Firma\" + LastCompany + "\settings.xml"
        xdcompanysettings.Load(companysettings)
    End Sub

    Public Sub ReloadArtikelliste() Implements IDatabase.ReloadArticleDatabase
        artikelliste = _directory + "Firma\" + LastCompany + "\artikelliste.xml"
        InitializeArtikelliste(artikelliste)
        xdartikel = New XmlDocument
        xdartikel.Load(_directory + "Firma\" + LastCompany + "\artikelliste.xml")
    End Sub

    Public Sub ReloadAuftragsliste() Implements IDatabase.ReloadOrderDatabase
        auftragsliste = _directory + "Firma\" + LastCompany + "\auftragsliste.xml"
        InitializeAuftragsliste(auftragsliste)
        XmlOrders = New XmlDocument
        XmlOrders.Load(_directory + "Firma\" + LastCompany + "\auftragsliste.xml")
    End Sub

    Public Sub ReloadKundenliste() Implements IDatabase.ReloadCustomerDatabase
        kundenliste = _directory + "Firma\" + LastCompany + "\kundenliste.xml"
        InitializeKundenliste(kundenliste)
        xdkunden = New XmlDocument
        xdkunden.Load(_directory + "Firma\" + LastCompany + "\kundenliste.xml")
    End Sub

    Public Sub ReloadKategorieliste() Implements IDatabase.ReloadCategoryDatabase
        kategorieliste = _directory + "Firma\" + LastCompany + "\kategorieliste.xml"
        InitializeKategorieliste(kategorieliste)
        xdkategorien = New XmlDocument
        xdkategorien.Load(_directory + "Firma\" + LastCompany + "\kategorieliste.xml")
    End Sub

    Public Sub ReloadAll() Implements IDatabase.ReloadAllDatabases
        xdglobalsettings = New XmlDocument
        xdglobalsettings.Load(_directory + "\Firma\globalsettings.xml")

        artikelliste = _directory + "Firma\" + LastCompany + "\artikelliste.xml"
        auftragsliste = _directory + "Firma\" + LastCompany + "\auftragsliste.xml"
        kundenliste = _directory + "Firma\" + LastCompany + "\kundenliste.xml"
        kategorieliste = _directory + "Firma\" + LastCompany + "\kategorieliste.xml"
        companysettings = _directory + "Firma\" + LastCompany + "\settings.xml"
        temp = _directory + "Firma\" + LastCompany + "\opentemp.xml"

        InitializeArtikelliste(artikelliste)
        InitializeAuftragsliste(auftragsliste)
        InitializeKundenliste(kundenliste)
        InitializeKategorieliste(kategorieliste)
        InitializeCompanySettings(companysettings)
        InitializeTempliste(temp)

        xdartikel = New XmlDocument
        xdartikel.Load(_directory + "Firma\" + LastCompany + "\artikelliste.xml")

        XmlOrders = New XmlDocument
        XmlOrders.Load(_directory + "Firma\" + LastCompany + "\auftragsliste.xml")

        xdkunden = New XmlDocument
        xdkunden.Load(_directory + "Firma\" + LastCompany + "\kundenliste.xml")

        xdkategorien = New XmlDocument
        xdkategorien.Load(_directory + "Firma\" + LastCompany + "\kategorieliste.xml")

        xdcompanysettings = New XmlDocument
        xdcompanysettings.Load(companysettings)

        xdtemp = New XmlDocument
        xdtemp.Load(temp)
    End Sub
#End Region

#Region "Global Settings"
    Public Property LastCompany() As String Implements IDatabase.LastCompany
        Set(ByVal value As String)
            Try
                Dim root As Xml.XmlElement = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/LastCompany"), Xml.XmlElement)
                If Not root Is Nothing Then
                    'Schlüssel vorhanden
                    root.InnerText = value
                Else
                    root = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings"), Xml.XmlElement)
                    Dim Node As XmlElement
                    Node = xdglobalsettings.CreateElement("LastCompany")
                    Node.InnerText = value
                    If Not root Is Nothing Then
                        root.AppendChild(Node)
                    End If
                End If
            Catch ex As Exception
            End Try
            xdglobalsettings.Save(_directory + "\Firma\globalsettings.xml")
        End Set
        Get
            Dim Node As Xml.XmlElement = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/LastCompany"), Xml.XmlElement)
            If Not Node Is Nothing Then
                Return Node.InnerText
            Else
                Return Nothing
            End If
        End Get
    End Property

    Public Property Steuerbezeichnung As String Implements IDatabase.TaxDescription
        Get
            Dim Node As Xml.XmlElement = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/Steuerbezeichnung"), Xml.XmlElement)
            If Not Node Is Nothing Then
                Return Node.InnerText
            Else
                Return Nothing
            End If
        End Get
        Set(value As String)
            Try
                Dim root As Xml.XmlElement = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/Steuerbezeichnung"), Xml.XmlElement)
                If Not root Is Nothing Then
                    'Schlüssel vorhanden
                    root.InnerText = value
                Else
                    root = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings"), Xml.XmlElement)
                    Dim Node As XmlElement
                    Node = xdglobalsettings.CreateElement("Steuerbezeichnung")
                    Node.InnerText = value
                    If Not root Is Nothing Then
                        root.AppendChild(Node)
                    End If
                End If
            Catch ex As Exception
            End Try
            Try
SaveXML:        xdglobalsettings.Save(_directory + "\Firma\globalsettings.xml")
            Catch ex As Exception
                System.Threading.Thread.Sleep(100)
                GoTo SaveXML
            End Try
        End Set
    End Property

    Public ReadOnly Property ListOfTaxes As ObservableCollection(Of TaxClass) Implements IDatabase.ListOfTaxes
        Get
            Try
                Dim temp As New ObservableCollection(Of TaxClass)
                Dim root As XmlElement = xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/Taxes")
                Dim nodeList As XmlNodeList = root.GetElementsByTagName("Tax")
                Dim list As IEnumerator = nodeList.GetEnumerator
                Do While (list.MoveNext())
                    Dim item As XmlElement
                    item = CType(list.Current, XmlElement)
                    temp.Add(New TaxClass(item.Item("Name").InnerText, item.Item("TaxRate").InnerText, Me))
                Loop
                Return temp
            Catch ex As Exception
                Return New ObservableCollection(Of TaxClass)
            End Try
        End Get
    End Property

    Public Sub AddTax(ByVal Tax As TaxClass) Implements IDatabase.SaveOrUpdateTax
        Try
            Dim root As Xml.XmlElement = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/Taxes"), Xml.XmlElement)
            If root IsNot Nothing Then
                Dim nodeList As XmlNodeList = root.GetElementsByTagName("Tax")
                Dim list As IEnumerator = nodeList.GetEnumerator
                Do While (list.MoveNext())
                    Dim item As XmlElement
                    item = CType(list.Current, XmlElement)
                    If item.Item("Name").InnerText = Tax.Name Then
                        item.Item("TaxRate").InnerText = Tax.TaxRate
                        xdglobalsettings.Save(_directory + "\Firma\globalsettings.xml")
                        Exit Sub
                    End If
                Loop
            End If

            Dim Node As XmlElement
            Node = xdglobalsettings.CreateElement("Tax")

            Dim item1, item2 As XmlElement
            item1 = xdglobalsettings.CreateElement("Name")
            item1.InnerText = Tax.Name
            item2 = xdglobalsettings.CreateElement("TaxRate")
            item2.InnerText = Tax.TaxRate

            Node.AppendChild(item1)
            Node.AppendChild(item2)

            If Not root Is Nothing Then
                root.AppendChild(Node)
            Else
                root = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings"), Xml.XmlElement)
                Dim root2 As XmlElement = xdglobalsettings.CreateElement("Taxes")
                root2.AppendChild(Node)
                root.AppendChild(root2)
            End If
        Catch ex As Exception
        End Try
        xdglobalsettings.Save(_directory + "\Firma\globalsettings.xml")
    End Sub

    Public ReadOnly Property ListOfUnits() As ObservableCollection(Of Unit) Implements IDatabase.ListOfUnits
        Get
            Dim temp As New ObservableCollection(Of Unit)
            Dim root As XmlElement = xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/Units")
            If root IsNot Nothing Then
                Dim nodeList As XmlNodeList = root.GetElementsByTagName("Unit")
                Dim list As IEnumerator = nodeList.GetEnumerator
                Do While (list.MoveNext())
                    Dim item As XmlElement
                    item = CType(list.Current, XmlElement)
                    Dim ti = New Unit(item.Item("Name").InnerText, item.Item("ShortName").InnerText, Me)
                    If item.Item("UnitFormat") IsNot Nothing Then
                        ti.UnitFormat = item.Item("UnitFormat").InnerText
                    End If
                    temp.Add(ti)
                Loop
            End If
            Return temp
        End Get
    End Property

    ''' <summary>
    ''' Saves a new Unit into the XML-Database
    ''' </summary>
    ''' <param name="Unit">The Unit you want to save</param>
    ''' <remarks></remarks>
    Public Sub AddUnit(ByVal Unit As Unit) Implements IDatabase.SaveOrUpdateUnit
        Try
            Dim root As Xml.XmlElement = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/Units"), Xml.XmlElement)
            If root IsNot Nothing Then
                Dim nodeList As XmlNodeList = root.GetElementsByTagName("Unit")
                Dim list As IEnumerator = nodeList.GetEnumerator
                Do While (list.MoveNext())
                    Dim item As XmlElement
                    item = CType(list.Current, XmlElement)
                    If item.Item("Name").InnerText = Unit.Name Then
                        item.Item("Name").InnerText = Unit.Name
                        item.Item("ShortName").InnerText = Unit.ShortName
                        If item.Item("UnitFormat") IsNot Nothing Then
                            item.Item("UnitFormat").InnerText = Unit.UnitFormat
                        Else
                            Dim temp = xdglobalsettings.CreateElement("UnitFormat")
                            temp.InnerText = Unit.UnitFormat
                            item.AppendChild(temp)
                        End If
                        xdglobalsettings.Save(_directory + "\Firma\globalsettings.xml")
                        Exit Sub
                    End If
                Loop
            End If

            ' If the methode is not exited by the do-loop (aka there is not this name in the file), we create a new

            Dim Node As XmlElement
            Node = xdglobalsettings.CreateElement("Unit")

            Dim item1, item2 As XmlElement
            item1 = xdglobalsettings.CreateElement("Name")
            item1.InnerText = Unit.Name
            item2 = xdglobalsettings.CreateElement("ShortName")
            item2.InnerText = Unit.ShortName

            Node.AppendChild(item1)
            Node.AppendChild(item2)

            item2 = xdglobalsettings.CreateElement("UnitFormat")
            item2.InnerText = Unit.UnitFormat

            Node.AppendChild(item2)

            If Not root Is Nothing Then
                root.AppendChild(Node)
            Else
                root = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings"), Xml.XmlElement)
                Dim root2 As XmlElement = xdglobalsettings.CreateElement("Units")
                root2.AppendChild(Node)
                root.AppendChild(root2)
            End If

        Catch ex As Exception
        End Try
        xdglobalsettings.Save(_directory + "\Firma\globalsettings.xml")
    End Sub

    Public ReadOnly Property ListOfPaymentMethodes As ObservableCollection(Of PaymentMethode) Implements IDatabase.ListOfPaymentMethodes
        Get
            Try
                Dim temp As New ObservableCollection(Of PaymentMethode)
                Dim root As XmlElement = xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/Zahlungsmethoden")
                Dim nodeList As XmlNodeList = root.GetElementsByTagName("Zahlungsmethode")
                Dim list As IEnumerator = nodeList.GetEnumerator
                Do While (list.MoveNext())
                    Dim item As XmlElement
                    item = CType(list.Current, XmlElement)
                    temp.Add(New PaymentMethode(item.Item("Name").InnerText, item.Item("Text").InnerText, item.Item("Abzug").InnerText))
                Loop
                Return temp
            Catch ex As Exception
                Return New ObservableCollection(Of PaymentMethode)
            End Try
        End Get
    End Property

    Public Sub AddPaymentMethode(ByVal Zahlung As PaymentMethode) Implements IDatabase.SaveOrUpdatePaymentMethode
        Try
            Dim root As Xml.XmlElement = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/Zahlungsmethoden"), Xml.XmlElement)
            If root IsNot Nothing Then
                Dim nodeList As XmlNodeList = root.GetElementsByTagName("Zahlungsmethode")
                Dim list As IEnumerator = nodeList.GetEnumerator
                Do While (list.MoveNext())
                    Dim item As XmlElement
                    item = CType(list.Current, XmlElement)
                    If item.Item("Name").InnerText = Zahlung.Name Then
                        item.Item("Name").InnerText = Zahlung.Name
                        item.Item("Text").InnerText = Zahlung.Text
                        item.Item("Abzug").InnerText = Zahlung.Reduction
                        xdglobalsettings.Save(_directory + "\Firma\globalsettings.xml")
                        Exit Sub
                    End If
                Loop
            End If

            ' If the methode is not exited by the do-loop (aka there is not this name in the file), we create a new

            Dim Node As XmlElement
            Node = xdglobalsettings.CreateElement("Zahlungsmethode")

            Dim item1, item2, item3 As XmlElement
            item1 = xdglobalsettings.CreateElement("Name")
            item1.InnerText = Zahlung.Name
            item2 = xdglobalsettings.CreateElement("Text")
            item2.InnerText = Zahlung.Text
            item3 = xdglobalsettings.CreateElement("Abzug")
            item3.InnerText = Zahlung.Reduction

            Node.AppendChild(item1)
            Node.AppendChild(item2)
            Node.AppendChild(item3)

            If Not root Is Nothing Then
                root.AppendChild(Node)
            Else
                root = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings"), Xml.XmlElement)
                Dim root2 As XmlElement = xdglobalsettings.CreateElement("Zahlungsmethoden")
                root2.AppendChild(Node)
                root.AppendChild(root2)
            End If
        Catch ex As Exception : End Try
        xdglobalsettings.Save(_directory + "\Firma\globalsettings.xml")
    End Sub

    Public ReadOnly Property ListOfOrderTexts() As ObservableCollection(Of nHibernate.Models.OrderTextModel) Implements IDatabase.ListOfOrderTexts
        Get
            Dim output As New ObservableCollection(Of nHibernate.Models.OrderTextModel)

            Dim root As XmlElement = xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/AuftragsTexte")
            If root IsNot Nothing Then
                Dim nodeList As XmlNodeList = root.GetElementsByTagName("AuftragsText")
                Dim list As IEnumerator = nodeList.GetEnumerator
                Do While (list.MoveNext())
                    Dim item As XmlElement
                    item = CType(list.Current, XmlElement)
                    output.Add(New nHibernate.Models.OrderTextModel With {.Name = item.Item("Name").InnerText, .Text = item.Item("Text").InnerText})
                Loop
            End If
            Return output
        End Get
    End Property

    Public Sub AddOrderText(current As nHibernate.Models.OrderTextModel) Implements IDatabase.SaveOrUpdateOrderText
        Try
            Dim root As Xml.XmlElement = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/AuftragsTexte"), Xml.XmlElement)
            If root IsNot Nothing Then
                Dim nodeList As XmlNodeList = root.GetElementsByTagName("AuftragsText")
                Dim list As IEnumerator = nodeList.GetEnumerator
                Do While (list.MoveNext())
                    Dim item As XmlElement
                    item = CType(list.Current, XmlElement)
                    If item.Item("Name").InnerText = current.Name Then
                        item.Item("Text").InnerText = current.Text
                        xdglobalsettings.Save(_directory + "\Firma\globalsettings.xml")
                        Exit Sub
                    End If
                Loop
            End If

            ' If the methode is not exited by the do-loop (aka there is not this name in the file), we create a new

            Dim Node As XmlElement
            Node = xdglobalsettings.CreateElement("AuftragsText")

            Dim item1 As XmlElement = xdglobalsettings.CreateElement("Name")
            item1.InnerText = current.Name

            Dim item2 As XmlElement = xdglobalsettings.CreateElement("Text")
            item2.InnerText = current.Text

            Node.AppendChild(item1)
            Node.AppendChild(item2)

            If Not root Is Nothing Then
                root.AppendChild(Node)
            Else
                root = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings"), Xml.XmlElement)
                Dim root2 As XmlElement = xdglobalsettings.CreateElement("AuftragsTexte")
                root2.AppendChild(Node)
                root.AppendChild(root2)
            End If
        Catch ex As Exception
        End Try
        xdglobalsettings.Save(_directory + "\Firma\globalsettings.xml")
    End Sub

    Public Property LastCustomLayout As String Implements IDatabase.LastCustomLayout
        Get
            Dim Node As Xml.XmlElement = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/LastCustomLayout"), Xml.XmlElement)
            If Not Node Is Nothing Then
                Return Node.InnerText
            Else
                Return Nothing
            End If
        End Get
        Set(value As String)
            Dim Node As Xml.XmlElement = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings/LastCustomLayout"), Xml.XmlElement)
            If Not Node Is Nothing Then
                Node.InnerText = value
            Else
                Node = CType(xdglobalsettings.DocumentElement.SelectSingleNode("/Settings"), Xml.XmlElement)
                Dim element As XmlElement = xdglobalsettings.CreateElement("LastCustomLayout")
                element.InnerText = value
                Node.AppendChild(element)
            End If
            xdglobalsettings.Save(_directory + "\Firma\globalsettings.xml")
        End Set
    End Property

    Public Function GetSettingByKey(key As String) As String Implements IDatabase.GetSettingByKey
        'query for a value
        Dim Node As Xml.XmlNode = xdglobalsettings.DocumentElement.SelectSingleNode( _
                                  "/Settings/setting[@key=""" & key & """]")

        'return the value or nothing if it doesn't exist
        If Not Node Is Nothing Then
            Return Node.Attributes.GetNamedItem("value").Value
        Else
            Return ""
        End If
    End Function

    Public Sub SetSettingByKey(key As String, value As String) Implements IDatabase.SetSettingByKey
        Try
            'get the value
            Dim Node As Xml.XmlElement = CType(xdglobalsettings.DocumentElement.SelectSingleNode( _
                                               "/Settings/setting[@key=""" & _
                                               key & """]"), Xml.XmlElement)
            If Not Node Is Nothing Then
                'key found, set the value
                Node.Attributes.GetNamedItem("value").Value = value
            Else
                'key not found, create it
                Node = xdglobalsettings.CreateElement("setting")
                Node.SetAttribute("key", key)
                Node.SetAttribute("value", value)

                'look for the appsettings node
                Dim Root As Xml.XmlNode = xdglobalsettings.DocumentElement.SelectSingleNode("/Settings")

                'add the new child node (this key)
                If Not Root Is Nothing Then
                    Root.AppendChild(Node)
                Else

                End If
            End If
        Catch ex As Exception

        End Try
        xdglobalsettings.Save(_directory + "\Firma\globalsettings.xml")
    End Sub
#End Region

#Region "Company"
    Private Sub SaveSetting(ByVal key As String, ByVal value As String)
        Try
            'get the value
            Dim Node As Xml.XmlElement = CType(xdcompanysettings.DocumentElement.SelectSingleNode( _
                                               "/company/settings/setting[@key=""" & _
                                               key & """]"), Xml.XmlElement)
            If Not Node Is Nothing Then
                'key found, set the value
                Node.Attributes.GetNamedItem("value").Value = value
            Else
                'key not found, create it
                Node = xdcompanysettings.CreateElement("setting")
                Node.SetAttribute("key", key)
                Node.SetAttribute("value", value)

                'look for the appsettings node
                Dim Root As Xml.XmlNode = xdcompanysettings.DocumentElement.SelectSingleNode("/company/settings")

                'add the new child node (this key)
                If Not Root Is Nothing Then
                    Root.AppendChild(Node)
                Else
                    Try
                        ' node didn't exist, add it before adding the new child
                        Root = xdcompanysettings.DocumentElement.SelectSingleNode("/company")
                        Root.AppendChild(xdcompanysettings.CreateElement("settings"))
                        Root = xdcompanysettings.DocumentElement.SelectSingleNode("/company/settings")
                        Root.AppendChild(Node)
                    Catch ex As Exception
                        'failed adding node, throw an error
                        Throw New Exception("Could not set value for company settings", ex)
                    End Try
                End If
            End If
        Catch : End Try
        xdcompanysettings.Save(companysettings)
    End Sub

    ''' <summary>
    ''' Doc is an reference. You have to save it on your own after methode is passed
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="value"></param>
    ''' <param name="doc"></param>
    ''' <remarks></remarks>
    Private Sub SaveSetting(ByVal key As String, ByVal value As String, ByRef doc As Xml.XmlDocument)
        Try
            'get the value
            Dim Node As Xml.XmlElement = CType(doc.DocumentElement.SelectSingleNode( _
                                               "/company/settings/setting[@key=""" & _
                                               key & """]"), Xml.XmlElement)
            If Not Node Is Nothing Then
                'key found, set the value
                Node.Attributes.GetNamedItem("value").Value = value
            Else
                'key not found, create it
                Node = xdcompanysettings.CreateElement("setting")
                Node.SetAttribute("key", key)
                Node.SetAttribute("value", value)

                'look for the appsettings node
                Dim Root As Xml.XmlNode = doc.DocumentElement.SelectSingleNode("/company/settings")

                'add the new child node (this key)
                If Not Root Is Nothing Then
                    Root.AppendChild(Node)
                Else
                    Try
                        ' node didn't exist, add it before adding the new child
                        Root = doc.DocumentElement.SelectSingleNode("/company")
                        Root.AppendChild(doc.CreateElement("settings"))
                        Root = doc.DocumentElement.SelectSingleNode("/company/settings")
                        Root.AppendChild(Node)
                    Catch ex As Exception
                        'failed adding node, throw an error
                        Throw New Exception("Could not set value for company settings", ex)
                    End Try
                End If
            End If
        Catch : End Try
    End Sub

    Private Function GetSetting(ByVal key As String) As String
        'query for a value
        Dim Node As Xml.XmlNode = xdcompanysettings.DocumentElement.SelectSingleNode( _
                                  "/company/settings/setting[@key=""" & key & """]")

        'return the value or nothing if it doesn't exist
        If Not Node Is Nothing Then
            Return Node.Attributes.GetNamedItem("value").Value
        Else
            Return Nothing
        End If
    End Function

    Private Function GetSetting(ByVal key As String, ByRef doc As Xml.XmlDocument) As String
        'query for a value
        Dim Node As Xml.XmlNode = doc.DocumentElement.SelectSingleNode( _
                                  "/company/settings/setting[@key=""" & key & """]")

        'return the value or nothing if it doesn't exist
        If Not Node Is Nothing Then
            Return Node.Attributes.GetNamedItem("value").Value
        Else
            Return ""
        End If
    End Function

    Public Property CompanyAdress As Address 'Implements IDatabase.CompanyAddress
        Get
            Dim temp As New Address()
            temp.Street = GetSetting("Strasse")
            temp.No = GetSetting("Hausnummer")
            temp.ZipCode = GetSetting("PLZ")
            temp.City = GetSetting("Stadt")
            temp.Country = GetSetting("Country")
            temp.Addition = GetSetting("Addition")
            Return temp
        End Get
        Set(value As Address)
            SaveSetting("Addition", value.Addition)
            SaveSetting("Strasse", value.Street)
            SaveSetting("Hausnummer", value.No)
            SaveSetting("PLZ", value.ZipCode)
            SaveSetting("Stadt", value.City)
            SaveSetting("Country", value.Country)
        End Set
    End Property

    Public Property Steuernummer As String 'Implements IDatabase.TaxID
        Get
            Return GetSetting("Steuernummer")
        End Get
        Set(value As String)
            SaveSetting("Steuernummer", value)
        End Set
    End Property

    Public Property USt_Id As String 'Implements IDatabase.TradeID
        Get
            Return GetSetting("USt_ID")
        End Get
        Set(value As String)
            SaveSetting("USt_ID", value)
        End Set
    End Property

    Public Function GetCompanySettings(companyname As String) As nHibernate.Models.CompanySettingsModel Implements IDatabase.GetCompanySettings
        Dim directory = _directory + "Firma\" + companyname
        If File.Exists(directory + "\settings.xml") Then
            Dim doc As New Xml.XmlDocument : doc.Load(directory + "\settings.xml")
            Dim item As New nHibernate.Models.CompanySettingsModel
            With item
                .Addition = GetSetting("Addition", doc)
                .Street = GetSetting("Strasse", doc)
                .No = GetSetting("Hausnummer", doc)
                .ZipCode = GetSetting("PLZ", doc)
                .City = GetSetting("Stadt", doc)
                .Country = GetSetting("Country", doc)
                .CompanyName = companyname
                .TaxID = GetSetting("Steuernummer", doc)
                .TradeID = GetSetting("USt_ID", doc)
            End With
            Return item
        End If
        Return Nothing
    End Function

    Public Sub SaveOrUpdateCompanySettings(settings As nHibernate.Models.CompanySettingsModel) Implements IDatabase.SaveOrUpdateCompanySettings
        If Not Directory.Exists(_directory + "\Firma\" + settings.CompanyName) Then
            Directory.CreateDirectory(_directory + "\Firma\" + settings.CompanyName)
        End If
        Dim temp = LastCompany
        LastCompany = settings.CompanyName
        ReloadAll()
        USt_Id = settings.TradeID
        Steuernummer = settings.TaxID
        CompanyAdress = New Address With {.Addition = settings.Addition, .City = settings.City, .Street = settings.Street, .No = settings.No, .ZipCode = settings.ZipCode, .Country = settings.Country}

        If Not String.IsNullOrEmpty(temp) Then
            LastCompany = temp
            ReloadAll()
        End If
    End Sub

    Public Function GetAllCompanys() As IList(Of nHibernate.Models.CompanySettingsModel) Implements IDatabase.GetAllCompanys
        Dim output As New List(Of nHibernate.Models.CompanySettingsModel)
        For Each directory In My.Computer.FileSystem.GetDirectories(_directory + "Firma\", FileIO.SearchOption.SearchTopLevelOnly)
            Dim cname = directory.Replace(_directory + "Firma\", "")
            If File.Exists(directory + "\settings.xml") Then
                Dim doc As New Xml.XmlDocument : doc.Load(directory + "\settings.xml")
                Dim item As New nHibernate.Models.CompanySettingsModel
                With item
                    .Addition = GetSetting("Addition", doc)
                    .Street = GetSetting("Strasse", doc)
                    .No = GetSetting("Hausnummer", doc)
                    .ZipCode = GetSetting("PLZ", doc)
                    .City = GetSetting("Stadt", doc)
                    .Country = GetSetting("Country", doc)
                    .CompanyName = cname
                    .TaxID = GetSetting("Steuernummer", doc)
                    .TradeID = GetSetting("USt_ID", doc)
                End With
                output.Add(item)
            End If
        Next
        Return output
    End Function

#End Region

#Region "Article"
    ''' <summary>
    ''' Gibt den gesamten Artikel unter der gegebenen Artikelnummer zurück
    ''' </summary>
    ''' <param name="ArtikelNummer">Artikelnummer des gesuchten Artikels</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetArticle(ByVal ArtikelNummer As String, usr As User) As Article Implements IDatabase.GetArticle
        Try
            If usr.CanReadArticle = False Then
                RaiseEvent UserRightsMissing(User.ArticleReadDenied)
                Return New Article()
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.ArticleReadDenied)
            Return New Article()
        End Try
        Try
            'get the value
            Dim Node As Xml.XmlElement = CType(xdartikel.DocumentElement.SelectSingleNode("/Artikelliste/Artikel[@ArtikelNr=""" & ArtikelNummer & """]"), Xml.XmlElement)
            If Not Node Is Nothing Then
                Dim art As New Article()
                art.ArticleDescription = Node.Item("Artikelbezeichnung").InnerText
                art.ArticleText = Node.Item("Artikeltext").InnerText
                art.ArticleUnit = Unit.GetByName(Node.Item("Einheit").InnerText, Me)
                Try
                    art.ArticlePrice1.IsGross = CBool(Node.Item("Artikelpreis").Item("Preis1Typ").InnerText) : art.ArticlePrice1.Amount = CDec(Node.Item("Artikelpreis").Item("Preis1").InnerText)
                    art.ArticlePrice2.IsGross = CBool(Node.Item("Artikelpreis").Item("Preis2Typ").InnerText) : art.ArticlePrice2.Amount = CDec(Node.Item("Artikelpreis").Item("Preis2").InnerText)
                    art.ArticlePrice3.IsGross = CBool(Node.Item("Artikelpreis").Item("Preis3Typ").InnerText) : art.ArticlePrice3.Amount = CDec(Node.Item("Artikelpreis").Item("Preis3").InnerText)
                Catch : End Try
                Try
                    art.ArticleCategory = Node.Item("Kategorie").InnerText
                Catch : art.ArticleCategory = Nothing : End Try

                art.TaxClass = TaxClass.GetByName(Node.Item("Steuerklasse").InnerText, Me)
                art.ArticleID = ArtikelNummer

                Try
                    art.ArticleWeight = CDec(Node.Item("Artikelgewicht").InnerText)
                Catch ex As Exception
                    art.ArticleWeight = 0
                End Try

                Return art
            ElseIf ArtikelNummer = "-1" Then : Return OrderedArticle.EmptyArticle : Else
                Return Nothing
            End If
        Catch ex As Exception
            Console.Write(ex.ToString)
            Return Nothing
        End Try
    End Function

    ''' <summary>
    ''' Gibt alle Artikel in der Datenbank in einer Collection zurück
    ''' </summary>
    ''' <returns>Gibt den Typ Artikel in einer Collection zurück</returns>
    ''' <remarks></remarks>
    Public Function GetAllArticles(usr As User) As IList(Of ArticlePreviewModel) Implements IDatabase.GetAllArticles
        Try
            If usr.CanReadArticle = False Then
                RaiseEvent UserRightsMissing(User.ArticleReadDenied)
                Return New ObservableCollection(Of ArticlePreviewModel)
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.ArticleReadDenied)
            Return New ObservableCollection(Of ArticlePreviewModel)
        End Try

        Dim root As XmlElement = xdartikel.DocumentElement
        Dim nodeList As XmlNodeList = root.GetElementsByTagName("Artikel")
        Dim list As IEnumerator = nodeList.GetEnumerator
        Dim rlist As New ObservableCollection(Of ArticlePreviewModel)

        Dim artikelliste As New Collection(Of XmlElement)

        Do While (list.MoveNext())
            artikelliste.Add(list.Current)
        Loop
        Dim mut As New Mutex
        Parallel.ForEach(artikelliste, Sub(item)
                                           Dim tmpcat As String = ""
                                           Try : tmpcat = item.Item("Kategorie").InnerText
                                           Catch : End Try

                                           Dim t As New ArticlePreviewModel() With {.ArticleDescription = item.Item("Artikelbezeichnung").InnerText, .ArticleID = item.Attributes.ItemOf("ArtikelNr").InnerText, .ArticleUnit = item.Item("Einheit").InnerText, _
                                                                                    .ArticlePrice = New Money(CDec(item.Item("Artikelpreis").Item("Preis1").InnerText)), .Category = tmpcat}
                                           mut.WaitOne()
                                           rlist.Add(t)
                                           mut.ReleaseMutex()
                                       End Sub)
        Return rlist
    End Function

    ''' <summary>
    ''' Prüft, ob die gegebene Artikelnummer schon in der Datenbank vorhanden ist.
    ''' </summary>
    ''' <param name="ArtikelNummer">Artikelnummer, die es zu prüfen gilt</param>
    ''' <returns>Gibt True zurück, falls ein Artikel vorhanden ist</returns>
    ''' <remarks></remarks>
    Public Function ExistsArticle(ByVal ArtikelNummer As String, usr As User) As Boolean Implements IDatabase.ArticleExists
        Try
            If usr.CanReadArticle = False Then
                RaiseEvent UserRightsMissing(User.ArticleReadDenied)
                Return False
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.ArticleReadDenied)
            Return False
        End Try

        Try
            'get the value
            Dim Node As Xml.XmlElement = CType(xdartikel.DocumentElement.SelectSingleNode("/Artikelliste/Artikel[@ArtikelNr=""" & ArtikelNummer & """]"), Xml.XmlElement)
            If Not Node Is Nothing Then
                Return True
            Else
                Return False
            End If
        Catch
            Return False
        End Try
    End Function

    Public Sub DeleteArticle(ByVal ArtikelNummer As String, usr As User) Implements IDatabase.DeleteArticle
        Try
            If usr.CanWriteArticle = False Then
                RaiseEvent UserRightsMissing(User.ArticleWriteDenied)
                Exit Sub
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.ArticleWriteDenied)
            Exit Sub
        End Try

        Dim xpath As String = "/Artikelliste/Artikel[@ArtikelNr=""{0}""]"
        Dim artnr As String = ArtikelNummer
        xpath = String.Format(xpath, artnr)
        Dim item As XmlElement = CType(xdartikel.DocumentElement.SelectSingleNode(xpath), Xml.XmlElement) 'xd.DocumentElement
        If item IsNot Nothing Then
            Dim element As XmlElement = item.ParentNode
            element.RemoveChild(item)
            xdartikel.Save(artikelliste)
        End If
    End Sub

    ''' <summary>
    ''' Speichert den gegebenen Artikel in der Datenbank
    ''' </summary>
    ''' <param name="artikel">Ein Objekt des Typs Artikel</param>
    ''' <remarks></remarks>
    Public Sub SetArticle(ByVal artikel As Article, usr As User) Implements IDatabase.SaveOrUpdateArticle
        Try
            If usr.CanWriteArticle = False Then
                RaiseEvent UserRightsMissing(User.ArticleWriteDenied)
                Exit Sub
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.ArticleWriteDenied)
            Exit Sub
        End Try

        Try
            'get the value
            Dim Node As Xml.XmlElement = CType(xdartikel.DocumentElement.SelectSingleNode("/Artikelliste/Artikel[@ArtikelNr=""" & artikel.ArticleID & """]"), Xml.XmlElement)
            If Not Node Is Nothing Then
                'Schlüssel gefunden, Änderung vornehmen
                Node.Item("Artikelbezeichnung").InnerText = artikel.ArticleDescription
                Node.Item("Artikeltext").InnerText = artikel.ArticleText
                Node.Item("Einheit").InnerText = artikel.ArticleUnit.Name

                Node.Item("Artikelpreis").Item("Preis1").InnerText = artikel.ArticlePrice1.Amount.ToString
                Node.Item("Artikelpreis").Item("Preis1Typ").InnerText = Math.Abs(CInt(artikel.ArticlePrice1.IsGross))
                Node.Item("Artikelpreis").Item("Preis2").InnerText = artikel.ArticlePrice2.Amount.ToString
                Node.Item("Artikelpreis").Item("Preis2Typ").InnerText = Math.Abs(CInt(artikel.ArticlePrice2.IsGross))
                Node.Item("Artikelpreis").Item("Preis3").InnerText = artikel.ArticlePrice3.Amount.ToString
                Node.Item("Artikelpreis").Item("Preis3Typ").InnerText = Math.Abs(CInt(artikel.ArticlePrice3.IsGross))
                Try
                    Node.Item("Kategorie").InnerText = artikel.ArticleCategory
                Catch ex As Exception
                    Dim item As XmlElement = xdartikel.CreateElement("Kategorie")
                    item.InnerText = artikel.ArticleCategory
                    Node.AppendChild(item)
                End Try
                Try
                    Node.Item("Artikelgewicht").InnerText = artikel.ArticleWeight
                Catch ex As Exception
                    Dim item As XmlElement = xdartikel.CreateElement("Artikelgewicht")
                    item.InnerText = artikel.ArticleWeight
                    Node.AppendChild(item)
                End Try
            Else
                'Schlüssel nicht gefunden, neu erstellen
                Node = xdartikel.CreateElement("Artikel")
                Node.SetAttribute("ArtikelNr", artikel.ArticleID)

                Dim nodename As XmlElement
                nodename = xdartikel.CreateElement("Artikelbezeichnung")
                nodename.InnerText = artikel.ArticleDescription

                Dim nodebez As XmlElement
                nodebez = xdartikel.CreateElement("Artikeltext")
                nodebez.InnerText = artikel.ArticleText

                Dim nodeeinh As XmlElement
                nodeeinh = xdartikel.CreateElement("Einheit")
                nodeeinh.InnerText = artikel.ArticleUnit.Name

                Dim nodepreis As XmlElement
                nodepreis = xdartikel.CreateElement("Artikelpreis")
                Dim preis1 As XmlElement
                preis1 = xdartikel.CreateElement("Preis1")
                preis1.InnerText = artikel.ArticlePrice1.Amount.ToString
                Dim preis1t As XmlElement = xdartikel.CreateElement("Preis1Typ")
                preis1t.InnerText = Math.Abs(CInt(artikel.ArticlePrice1.IsGross))
                Dim preis2 As XmlElement
                preis2 = xdartikel.CreateElement("Preis2")
                preis2.InnerText = artikel.ArticlePrice2.Amount.ToString
                Dim preis2t As XmlElement = xdartikel.CreateElement("Preis2Typ")
                preis2t.InnerText = Math.Abs(CInt(artikel.ArticlePrice2.IsGross))
                Dim preis3 As XmlElement
                preis3 = xdartikel.CreateElement("Preis3")
                preis3.InnerText = artikel.ArticlePrice3.Amount.ToString
                Dim preis3t As XmlElement = xdartikel.CreateElement("Preis3Typ")
                preis3t.InnerText = Math.Abs(CInt(artikel.ArticlePrice3.IsGross))
                nodepreis.AppendChild(preis1) : nodepreis.AppendChild(preis1t) : nodepreis.AppendChild(preis2) : nodepreis.AppendChild(preis2t)
                nodepreis.AppendChild(preis3) : nodepreis.AppendChild(preis3t)

                Node.AppendChild(nodename) : Node.AppendChild(nodebez) : Node.AppendChild(nodepreis) : Node.AppendChild(nodeeinh)

                Dim stklasse As XmlElement = xdartikel.CreateElement("Steuerklasse")
                stklasse.InnerText = artikel.TaxClass.Name

                Dim kat As XmlElement = xdartikel.CreateElement("Kategorie")
                kat.InnerText = artikel.ArticleCategory

                Dim item As XmlElement = xdartikel.CreateElement("Artikelgewicht")
                item.InnerText = artikel.ArticleWeight

                Node.AppendChild(item)
                Node.AppendChild(kat)
                Node.AppendChild(stklasse)

                'Nach dem Hauptschlüssel suchen
                Dim Root As Xml.XmlNode = xdartikel.DocumentElement.SelectSingleNode("/Artikelliste")
                If Not Root Is Nothing Then
                    Root.AppendChild(Node)
                Else

                End If
            End If
            Try
                xdartikel.Save(artikelliste)
            Catch ex As Exception : End Try
        Catch ex As Exception : End Try
    End Sub
#End Region

#Region "Orders"
    Public Function AuftragExists(ByVal AuftragsNummer As String, ByVal Dokumenttyp As Dokumentart, usr As User) As Boolean Implements IDatabase.OrderExists
        Try
            If usr.CanReadOrder = False Then
                RaiseEvent UserRightsMissing(User.OrderReadDenied)
                Return False
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.OrderReadDenied)
            Return False
        End Try

        Dim xpath As String = "/Auftragsliste/Auftrag[@LaufendeNr=""{0}"" and @Dokumenttyp=""{1}""]"
        Dim aufnr As String = AuftragsNummer
        Dim typ As String = Dokumenttyp
        xpath = String.Format(xpath, aufnr, typ)
        Dim item As XmlElement = CType(XmlOrders.DocumentElement.SelectSingleNode(xpath), Xml.XmlElement) 'xd.DocumentElement
        If item IsNot Nothing Then
            Return True
        Else
            Return False
        End If
    End Function

    ''' <summary>
    ''' Gibt einen spezifischen Auftrag zurück
    ''' </summary>
    ''' <param name="AuftragsNummer">Die Auftragsnummer des Auftrags</param>
    ''' <param name="Dokumenttyp">Der Dokumenttyp</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetOrder(ByVal AuftragsNummer As String, ByVal Dokumenttyp As Dokumentart, usr As User) As Order Implements IDatabase.GetOrder
        Try
            If usr.CanReadOrder = False Then
                RaiseEvent UserRightsMissing(User.OrderReadDenied)
                Return Nothing
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.OrderReadDenied)
            Return Nothing
        End Try

        Dim xpath As String = "/Auftragsliste/Auftrag[@LaufendeNr=""{0}"" and @Dokumenttyp=""{1}""]"
        Dim aufnr As String = AuftragsNummer
        Dim typ As String = Dokumenttyp
        xpath = String.Format(xpath, aufnr, typ)
        Dim item As XmlElement = CType(XmlOrders.DocumentElement.SelectSingleNode(xpath), Xml.XmlElement)
        If item IsNot Nothing Then
            Return GetAuftragByXMLElement(item, usr)
        End If
    End Function

    Private Function GetOrderSetting(item As XmlElement, key As String) As String
        If item.Item(key) IsNot Nothing Then
            Return item.Item(key).InnerText
        Else
            Return ""
        End If
    End Function

    Private Function GetAuftragByXMLElement(ByVal item As XmlElement, usr As User) As Order
        Dim xmldoc As XDocument = XDocument.Parse("<item>" + item.InnerXml + "</item>")

        Dim auftrag As New Order()
        With auftrag
            auftrag.Datum = New Datum(item.Item("Datum").InnerText)
            auftrag.DokumentArt = item.Attributes("Dokumenttyp").InnerText
            auftrag.OrderID = (item.Attributes("LaufendeNr").InnerText)
            If item.Item("Kunde").Item("Kundennummer").InnerText = "" Then
                Try
                    .Customer = New Customer
                    .Customer.Address.Salutation = item.Item("Kunde").Item("Anrede").InnerText
                    .Customer.Address.Title = item.Item("Kunde").Item("Titel").InnerText
                    .Customer.Address.Forname = item.Item("Kunde").Item("Vorname").InnerText
                    .Customer.Address.Surname = item.Item("Kunde").Item("Nachname").InnerText
                    .Customer.Address.Addition = item.Item("Kunde").Item("Adresszusatz").InnerText
                    .Customer.Address.No = item.Item("Kunde").Item("Hausnummer").InnerText
                    .Customer.Address.Country = item.Item("Kunde").Item("Land").InnerText
                    .Customer.Address.ZipCode = item.Item("Kunde").Item("PLZ").InnerText
                    .Customer.Address.City = item.Item("Kunde").Item("Ort").InnerText
                    .Customer.Address.Street = item.Item("Kunde").Item("Strasse").InnerText
                Catch ex As Exception : End Try
            Else
                auftrag.Customer = GetCustomer(item.Item("Kunde").Item("Kundennummer").InnerText, usr)
            End If

            If xmldoc.Element("DeliveryAddress") IsNot Nothing Then
                .DeliveryAddress = New Address
                .DeliveryAddress.Salutation = item.Item("DeliveryAddress").Item("Salutation").InnerText
                .DeliveryAddress.Forname = item.Item("DeliveryAddress").Item("Forname").InnerText
                .DeliveryAddress.Surname = item.Item("DeliveryAddress").Item("Surname").InnerText
                .DeliveryAddress.Addition = item.Item("DeliveryAddress").Item("Addition").InnerText
                .DeliveryAddress.Street = item.Item("DeliveryAddress").Item("Street").InnerText
                .DeliveryAddress.No = item.Item("DeliveryAddress").Item("No").InnerText
                .DeliveryAddress.ZipCode = item.Item("DeliveryAddress").Item("Zip").InnerText
                .DeliveryAddress.City = item.Item("DeliveryAddress").Item("City").InnerText
                .DeliveryAddress.Country = item.Item("DeliveryAddress").Item("Country").InnerText
            Else
                .DeliveryAddress = Nothing
            End If

            '### Linked Orders ###'
            .LinkedFromOffer = GetOrderSetting(item, "LinkedFromOffer")
            .LinkedFromCredit = GetOrderSetting(item, "LinkedFromCredit")
            .LinkedFromInvoice = GetOrderSetting(item, "LinkedFromInvoice")
            .LinkedFromDelivery = GetOrderSetting(item, "LinkedFromDelivery")

            .LinkedToOffer = GetOrderSetting(item, "LinkedToOffer")
            .LinkedToCredit = GetOrderSetting(item, "LinkedToCredit")
            .LinkedToInvoice = GetOrderSetting(item, "LinkedToInvoice")
            .LinkedToDelivery = GetOrderSetting(item, "LinkedToDelivery")

            Dim articlelist = From article In xmldoc.Descendants("Auftragspositionen").Descendants("Artikel") Select article
            Dim ltlist As New List(Of OrderedArticle)
            Dim mutex2 As New Mutex
            Parallel.ForEach(articlelist, Sub(item2)
                                              Dim art As New OrderedArticle(GetArticle(item2.Element("Artikelnummer").Value, usr))
                                              art.OrderPrice.Amount = CDbl(item2.Element("Auftragspreis").Value)
                                              art.OrderPrice.IsGross = CBool(item2.Element("AuftragspreisTyp").Value)
                                              If item2.Element("Auftragsmenge") IsNot Nothing Then
                                                  art.OrderedAmount = item2.Element("Auftragsmenge").Value
                                              Else
                                                  art.OrderedAmount = 0
                                              End If

                                              If item2.Element("PositionsNummer") IsNot Nothing Then
                                                  art.OrderPosition = item2.Element("PositionsNummer").Value
                                              Else
                                                  art.OrderPosition = 0
                                              End If

                                              If item2.Element("Auftragsrabatt") IsNot Nothing Then
                                                  art.OrderRebate = item2.Element("Auftragsrabatt").Value
                                              Else
                                                  art.OrderRebate = 0
                                              End If
                                              If item2.Element("Auftragstext") IsNot Nothing Then
                                                  art.OrderText = item2.Element("Auftragstext").Value
                                              Else : art.OrderText = "" : End If
                                              art.OrderArticleID = Guid.NewGuid.ToString
                                              mutex2.WaitOne()
                                              ltlist.Add(art)
                                              mutex2.ReleaseMutex()
                                          End Sub)
            ltlist.Sort(New OrderedArticleSorter)
            For Each tarticle In ltlist
                auftrag.OrderedArticles.Add(tarticle)
            Next
        End With
        If xmldoc.Element("item").Elements("Gesamtrabatt").Any Then
            auftrag.Rebate = xmldoc.Element("item").Element("Gesamtrabatt").Value
        Else : auftrag.Rebate = 0 : End If
        If xmldoc.Element("item").Element("FesterAbzug") IsNot Nothing Then
            auftrag.Reduction = New Money(xmldoc.Element("item").Element("FesterAbzug").Value)
        Else : auftrag.Reduction = New Money(0) : End If
        If xmldoc.Element("item").Element("FesterAbzugText") IsNot Nothing Then
            auftrag.ReductionText = xmldoc.Element("item").Element("FesterAbzugText").Value
        Else : auftrag.ReductionText = "" : End If
        If xmldoc.Element("item").Elements("AuftragsText").Any Then
            auftrag.OrderText = xmldoc.Element("item").Element("AuftragsText").Value
        Else : auftrag.OrderText = "" : End If
        If xmldoc.Element("item").Element("TextBefore") IsNot Nothing Then
            auftrag.TextBefore = xmldoc.Element("item").Element("TextBefore").Value
        Else : auftrag.TextBefore = "" : End If
        If xmldoc.Element("item").Element("Zahlungsart") IsNot Nothing Then
            auftrag.PaymentMethode = PaymentMethode.GetByName(item.Item("Zahlungsart").InnerText, Me)
        Else : auftrag.PaymentMethode = Nothing : End If
        Try
            auftrag.LastEditBy = New nHibernate.Models.UserPreviewModel With {.UserName = xmldoc.Element("item").Element("LastEditBy").Attribute("name").Value, .UserID = xmldoc.Element("item").Element("LastEditBy").Attribute("id").Value}
        Catch : auftrag.LastEditBy = New nHibernate.Models.UserPreviewModel : End Try

        Return auftrag
    End Function

    Public Function GetAuftraegeInInterval(startdate As Date, enddate As Date, usr As User) As IList(Of OrderPreviewModel) Implements IDatabase.GetOrdersInInterval
        Try
            If usr.CanReadOrder = False Then
                RaiseEvent UserRightsMissing(User.OrderReadDenied)
                Return New ObservableCollection(Of OrderPreviewModel)
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.OrderReadDenied)
            Return New ObservableCollection(Of OrderPreviewModel)
        End Try

        Dim mutex As New Mutex
        Dim returnlist As New ObservableCollection(Of OrderPreviewModel)

        Dim root As XmlElement = XmlOrders.DocumentElement
        Dim nodeList As XmlNodeList = root.GetElementsByTagName("Auftrag")
        Dim list As IEnumerator = nodeList.GetEnumerator

        Dim collection As New Collection(Of XmlElement)
        Do While list.MoveNext
            collection.Add(list.Current)
        Loop

        Parallel.ForEach(collection, Sub(item)
                                         Dim auftragsdatum As New Datum(item.Item("Datum").InnerText)
                                         If startdate <= auftragsdatum.ToDate AndAlso enddate >= auftragsdatum.ToDate Then
                                             Dim auftrag As Order = GetAuftragByXMLElement(item, usr)
                                             mutex.WaitOne()
                                             returnlist.Add(New OrderPreviewModel With {.Date_ = auftrag.Datum.ToString, .CustomerName = auftrag.Customer.DisplayName, .CustomerID = auftrag.Customer.CustomerID, .OrderID = auftrag.OrderID, .OrderTyp = auftrag.DokumentArt, .Value = auftrag.TotalValue})
                                             mutex.ReleaseMutex()
                                         End If
                                     End Sub)
        Return returnlist
    End Function

    Public Function GetAuftraegeByCustomer(ByVal CustomID As String, usr As User, Optional ByVal startdate As Date = Nothing, Optional ByVal enddate As Date = Nothing) As IList(Of OrderPreviewModel) Implements IDatabase.GetOrdersByCustomer
        Try
            If usr.CanReadOrder = False Then
                RaiseEvent UserRightsMissing(User.OrderReadDenied)
                Return New ObservableCollection(Of OrderPreviewModel)
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.OrderReadDenied)
            Return New ObservableCollection(Of OrderPreviewModel)
        End Try

        Dim mutex As New Mutex
        Dim auftragslist As New ObservableCollection(Of OrderPreviewModel)
        Dim root As XmlElement = XmlOrders.DocumentElement
        Dim nodeList As XmlNodeList = root.GetElementsByTagName("Auftrag")
        Dim list As IEnumerator = nodeList.GetEnumerator

        Dim collection As New Collection(Of XmlElement)
        Do While list.MoveNext
            collection.Add(list.Current)
        Loop
        If startdate = Nothing AndAlso enddate = Nothing Then
            Parallel.ForEach(collection, Sub(item)
                                             If item.Item("Kunde").Item("Kundennummer").InnerText = CustomID Then
                                                 Dim auftrag = GetAuftragByXMLElement(item, usr)
                                                 mutex.WaitOne()
                                                 auftragslist.Add(New OrderPreviewModel With {.Date_ = auftrag.Datum.ToString, .CustomerID = auftrag.Customer.CustomerID, .CustomerName = auftrag.Customer.DisplayName, .OrderID = auftrag.OrderID, .OrderTyp = auftrag.DokumentArt, .Value = auftrag.TotalValue})
                                                 mutex.ReleaseMutex()
                                             End If
                                         End Sub)
        Else
            Parallel.ForEach(collection, Sub(item)
                                             Dim d1 As New Datum(item.Item("Datum").InnerText)
                                             Dim d As New Date(d1.Jahr, d1.Monat, d1.Tag)
                                             If IsDateBetween(startdate, enddate, d) Then
                                                 If item.Item("Kunde").Item("Kundennummer").InnerText = CustomID Then
                                                     Dim auftrag = GetAuftragByXMLElement(item, usr)
                                                     mutex.WaitOne()
                                                     auftragslist.Add(New OrderPreviewModel With {.Date_ = auftrag.Datum.ToString, .CustomerID = auftrag.Customer.CustomerID, .CustomerName = auftrag.Customer.DisplayName, .OrderID = auftrag.OrderID, .OrderTyp = auftrag.DokumentArt, .Value = auftrag.TotalValue})
                                                     mutex.ReleaseMutex()
                                                 End If
                                             End If
                                         End Sub)
        End If

        Return auftragslist
    End Function

    Public Function IsDateBetween(startdate As Date, enddate As Date, yourdate As Date) As Boolean
        If DateTime.Compare(startdate, yourdate) <= 0 Then
            If DateTime.Compare(enddate, yourdate) >= 0 Then
                Return True
            End If
        End If
        Return False
    End Function

    ''' <summary>
    ''' Method to load Articledata into an new instance from Auftrag from an existing xmlnode
    ''' </summary>
    ''' <param name="item"></param>
    ''' <returns></returns>
    ''' <remarks>This method does not set the customer!</remarks>
    Private Function GetAuftragArticlesByXmlNode(item As XmlElement) As Order
        Dim auftrag As New Order()
        Dim mutex As New Mutex
        If item IsNot Nothing Then
            auftrag.Datum = New Datum(item.Item("Datum").InnerText)
            'Aktueller Monat, alle zu einer DataTable hinzufügen
            With auftrag
                Dim liste2 As IEnumerator
                Dim nodelist2 As XmlNodeList = item.Item("Auftragspositionen").GetElementsByTagName("Artikel")
                liste2 = nodelist2.GetEnumerator
                Dim artikelliste As New Collection(Of XmlElement)
                Do While (liste2.MoveNext())
                    artikelliste.Add(liste2.Current)
                Loop
                Parallel.ForEach(artikelliste, Sub(item2)
                                                   Dim art As New OrderedArticle(New Article())
                                                   art.OrderPrice.Amount = CDbl(item2.Item("Auftragspreis").Value)
                                                   art.OrderPrice.IsGross = CBool(item2.Item("AuftragspreisTyp").Value)
                                                   art.OrderedAmount = item2.Item("Auftragsmenge").Value
                                                   Try
                                                       art.OrderRebate = item2.Item("Auftragsrabatt").InnerText
                                                   Catch ex As Exception
                                                       art.OrderRebate = "0"
                                                   End Try
                                                   mutex.WaitOne()
                                                   auftrag.OrderedArticles.Add(art)
                                                   mutex.ReleaseMutex()
                                               End Sub)
            End With
        End If
        Return auftrag
    End Function

    Public Function GetAllOrders(usr As User) As IList(Of OrderPreviewModel) Implements IDatabase.GetAllOrders
        Try
            If usr.CanReadOrder = False Then
                RaiseEvent UserRightsMissing(User.OrderReadDenied)
                Return New ObservableCollection(Of OrderPreviewModel)
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.OrderReadDenied)
            Return New ObservableCollection(Of OrderPreviewModel)
        End Try

        Dim mutex As New Mutex
        Dim returnlist As New ObservableCollection(Of OrderPreviewModel)

        Dim root As XmlElement = XmlOrders.DocumentElement
        Dim nodeList As XmlNodeList = root.GetElementsByTagName("Auftrag")
        Dim list As IEnumerator = nodeList.GetEnumerator

        Dim collection As New Collection(Of XmlElement)
        Do While list.MoveNext
            collection.Add(list.Current)
        Loop

        Parallel.ForEach(collection, Sub(item)
                                         Dim auftrag As Order = GetAuftragByXMLElement(item, usr)
                                         mutex.WaitOne()
                                         returnlist.Add(New OrderPreviewModel With {.Date_ = auftrag.Datum.ToString, .CustomerID = auftrag.Customer.CustomerID, .CustomerName = auftrag.Customer.DisplayName, .OrderID = auftrag.OrderID, .OrderTyp = CInt(auftrag.DokumentArt), .Value = auftrag.TotalValue})
                                         mutex.ReleaseMutex()
                                     End Sub)
        Return returnlist
    End Function

    Private Sub CheckAddOrderSetting(node As XmlElement, key As String, value As String)
        Try
            node.Item(key).InnerText = value
        Catch ex As Exception
            'Node existiert nicht
            Dim item As XmlElement = XmlOrders.CreateElement(key)
            item.InnerText = value
            node.AppendChild(item)
        End Try
    End Sub

    ''' <summary>
    ''' Speichert den übergebenen Auftrag unter der gegebenen laufenden Nummer und dem Dokumenttyp ab
    ''' </summary>
    ''' <param name="auftrag">Ein Objekt des Typs Auftrag</param>
    ''' <remarks></remarks>
    Public Sub SetOrder(ByVal auftrag As Order, usr As User) Implements IDatabase.SaveOrUpdateOrder
        Try
            If usr.CanWriteOrder = False Then
                RaiseEvent UserRightsMissing(User.OrderWriteDenied)
                Exit Sub
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.OrderWriteDenied)
            Exit Sub
        End Try
        Try
            'Den Schlüssel finden
            Dim xpath As String = "/Auftragsliste/Auftrag[@LaufendeNr=""{0}"" and @Dokumenttyp=""{1}""]"
            Dim aufnr As String = auftrag.OrderID
            Dim typ As Integer = auftrag.DokumentArt
            xpath = String.Format(xpath, aufnr, typ)

            Dim Node As Xml.XmlElement = CType(XmlOrders.DocumentElement.SelectSingleNode(xpath), Xml.XmlElement)
            If Not Node Is Nothing Then
                If Node.Attributes("Dokumenttyp").InnerText = auftrag.DokumentArt Then
                    'Schlüssel gefunden, Änderung vornehmen
                    Node.Item("Datum").InnerText = auftrag.Datum.ToString
                    Try
                        Node.Item("AuftragsText").InnerText = auftrag.OrderText
                    Catch ex As Exception
                        'Node existiert nicht
                        If Not String.IsNullOrEmpty(auftrag.OrderText) Then
                            Dim item As XmlElement = XmlOrders.CreateElement("AuftragsText")
                            item.InnerText = auftrag.OrderText
                            Node.AppendChild(item)
                        End If
                    End Try

                    Try
                        Node.Item("TextBefore").InnerText = auftrag.TextBefore
                    Catch ex As Exception
                        'Node existiert nicht
                        If Not String.IsNullOrEmpty(auftrag.TextBefore) Then
                            Dim item As XmlElement = XmlOrders.CreateElement("TextBefore")
                            item.InnerText = auftrag.TextBefore
                            Node.AppendChild(item)
                        End If
                    End Try

                    Try
                        Node.Item("FesterAbzug").InnerText = auftrag.Reduction.Amount
                    Catch ex As Exception
                        'Node existiert nicht
                        Dim item As XmlElement = XmlOrders.CreateElement("FesterAbzug")
                        item.InnerText = auftrag.Reduction.Amount
                        Node.AppendChild(item)
                    End Try

                    Try
                        Node.Item("FesterAbzugText").InnerText = auftrag.ReductionText
                    Catch ex As Exception
                        'Node existiert nicht
                        Dim item As XmlElement = XmlOrders.CreateElement("FesterAbzugText")
                        item.InnerText = auftrag.ReductionText
                        Node.AppendChild(item)
                    End Try

                    Try
                        Node.Item("Gesamtrabatt").InnerText = auftrag.Rebate
                    Catch ex As Exception
                        'Node existiert nicht
                        Dim item As XmlElement = XmlOrders.CreateElement("Gesamtrabatt")
                        item.InnerText = auftrag.Rebate
                        Node.AppendChild(item)
                    End Try

                    If auftrag.PaymentMethode IsNot Nothing Then
                        Try
                            Node.Item("Zahlungsart").InnerText = auftrag.PaymentMethode.Name
                        Catch ex As Exception
                            'Node existiert nicht
                            Dim item As XmlElement = XmlOrders.CreateElement("Zahlungsart")
                            item.InnerText = auftrag.PaymentMethode.Name
                            Node.AppendChild(item)
                        End Try
                    End If

                    Try
                        Node.Item("LastEditBy").SetAttribute("name", auftrag.LastEditBy.UserName)
                        Node.Item("LastEditBy").SetAttribute("id", auftrag.LastEditBy.UserID)
                    Catch ex As Exception
                        Dim item As XmlElement = XmlOrders.CreateElement("LastEditBy")
                        item.SetAttribute("name", auftrag.LastEditBy.UserName)
                        item.SetAttribute("id", auftrag.LastEditBy.UserID)
                        Node.AppendChild(item)
                    End Try


                    CheckAddOrderSetting(Node, "LinkedToInvoice", auftrag.LinkedToInvoice)
                    CheckAddOrderSetting(Node, "LinkedFromInvoice", auftrag.LinkedFromInvoice)

                    CheckAddOrderSetting(Node, "LinkedToDelivery", auftrag.LinkedToDelivery)
                    CheckAddOrderSetting(Node, "LinkedFromDelivery", auftrag.LinkedFromDelivery)

                    CheckAddOrderSetting(Node, "LinkedToOffer", auftrag.LinkedToOffer)
                    CheckAddOrderSetting(Node, "LinkedFromOffer", auftrag.LinkedFromOffer)

                    CheckAddOrderSetting(Node, "LinkedToCredit", auftrag.LinkedToCredit)
                    CheckAddOrderSetting(Node, "LinkedFromCredit", auftrag.LinkedFromCredit)

                    If Customer.IsEmpty(auftrag.Customer) = False Then
                        If auftrag.Customer.CustomerID = "" Then
                            '#### Manuelle Adresse ####'
                            Node.Item("Kunde").Item("Kundennummer").InnerText = Nothing
                            With auftrag.Customer
                                Node.Item("Kunde").Item("Anrede").InnerText = .Address.Salutation
                                Node.Item("Kunde").Item("Vorname").InnerText = .Address.Forname
                                Node.Item("Kunde").Item("Nachname").InnerText = .Address.Surname
                                Node.Item("Kunde").Item("Titel").InnerText = .Address.Title
                                Node.Item("Kunde").Item("Strasse").InnerText = .Address.Street
                                Node.Item("Kunde").Item("Hausnummer").InnerText = .Address.No
                                Node.Item("Kunde").Item("PLZ").InnerText = .Address.ZipCode
                                Node.Item("Kunde").Item("Ort").InnerText = .Address.City
                                Node.Item("Kunde").Item("Land").InnerText = .Address.Country
                                Node.Item("Kunde").Item("Adresszusatz").InnerText = .Address.Addition
                            End With
                        Else
                            Node.Item("Kunde").Item("Kundennummer").InnerText = auftrag.Customer.CustomerID
                        End If
                    End If

                    If auftrag.DeliveryAddress IsNot Nothing Then
                        With auftrag.DeliveryAddress
                            Try
                                Node.Item("DeliveryAddress").Item("Salutation").InnerText = .Salutation
                                Node.Item("DeliveryAddress").Item("Forname").InnerText = .Forname
                                Node.Item("DeliveryAddress").Item("Surname").InnerText = .Surname
                                Node.Item("DeliveryAddress").Item("Addition").InnerText = .Addition
                                Node.Item("DeliveryAddress").Item("Street").InnerText = .Street
                                Node.Item("DeliveryAddress").Item("No").InnerText = .No
                                Node.Item("DeliveryAddress").Item("Zip").InnerText = .ZipCode
                                Node.Item("DeliveryAddress").Item("City").InnerText = .City
                                Node.Item("DeliveryAddress").Item("Country").InnerText = .Country
                            Catch ex As Exception
                                'Node existiert noch nicht
                                Dim item As XmlElement = XmlOrders.CreateElement("DeliveryAddress")

                                Dim item2 As XmlElement = XmlOrders.CreateElement("Salutation")
                                item2.InnerText = .Salutation
                                item.AppendChild(item2)

                                item2 = XmlOrders.CreateElement("Forname")
                                item2.InnerText = .Forname
                                item.AppendChild(item2)

                                item2 = XmlOrders.CreateElement("Surname")
                                item2.InnerText = .Surname
                                item.AppendChild(item2)

                                item2 = XmlOrders.CreateElement("Addition")
                                item2.InnerText = .Addition
                                item.AppendChild(item2)

                                item2 = XmlOrders.CreateElement("Street")
                                item2.InnerText = .Street
                                item.AppendChild(item2)

                                item2 = XmlOrders.CreateElement("No")
                                item2.InnerText = .No
                                item.AppendChild(item2)

                                item2 = XmlOrders.CreateElement("Zip")
                                item2.InnerText = .ZipCode
                                item.AppendChild(item2)

                                item2 = XmlOrders.CreateElement("City")
                                item2.InnerText = .City
                                item.AppendChild(item2)

                                item2 = XmlOrders.CreateElement("Country")
                                item2.InnerText = .Country
                                item.AppendChild(item2)

                                Node.AppendChild(item)
                            End Try
                        End With
                    End If

                    Dim nodeList As XmlNodeList = Node.GetElementsByTagName("Auftragspositionen")
                    If nodeList.Count > 0 Then
                        Dim parent = nodeList.Item(0).ParentNode
                        parent.RemoveChild(nodeList.Item(0))
                    End If

                    '##### Auftragspositionen #####'
                    Dim nodepositionen As XmlElement
                    nodepositionen = XmlOrders.CreateElement("Auftragspositionen")
                    For Each art As OrderedArticle In auftrag.OrderedArticles
                        Dim root2 As XmlElement
                        root2 = XmlOrders.CreateElement("Artikel")

                        Dim item1, item2, item21, item3, item4, item5, item6 As XmlElement
                        item1 = XmlOrders.CreateElement("Artikelnummer")
                        item1.InnerText = art.ArticleID

                        item2 = XmlOrders.CreateElement("Auftragspreis")
                        item2.InnerText = art.OrderPrice.Amount.ToString

                        item21 = XmlOrders.CreateElement("AuftragspreisTyp")
                        item21.InnerText = Math.Abs(CInt(art.OrderPrice.IsGross))

                        item3 = XmlOrders.CreateElement("Auftragsmenge")
                        item3.InnerText = art.OrderedAmount.ToString

                        item4 = XmlOrders.CreateElement("Auftragsrabatt")
                        item4.InnerText = art.OrderRebate.ToString

                        item5 = XmlOrders.CreateElement("Auftragstext")
                        item5.InnerText = art.OrderText

                        item6 = XmlOrders.CreateElement("PositionsNummer")
                        item6.InnerText = art.OrderPosition

                        root2.AppendChild(item1)
                        root2.AppendChild(item2)
                        root2.AppendChild(item21)
                        root2.AppendChild(item3)
                        root2.AppendChild(item4)
                        root2.AppendChild(item5)
                        root2.AppendChild(item6)
                        nodepositionen.AppendChild(root2)
                    Next
                    Node.AppendChild(nodepositionen)
                Else
                    GoTo NeuAnlegen
                End If
            Else
                'Schlüssel nicht gefunden, neu erstellen
NeuAnlegen:     Node = XmlOrders.CreateElement("Auftrag")
                Node.SetAttribute("LaufendeNr", auftrag.OrderID.ToString)
                Node.SetAttribute("Dokumenttyp", auftrag.DokumentArt)

                Dim nodedatum As XmlElement
                nodedatum = XmlOrders.CreateElement("Datum")
                nodedatum.InnerText = auftrag.Datum.ToString
                Node.AppendChild(nodedatum)

                Dim item As XmlElement = XmlOrders.CreateElement("AuftragsText")
                item.InnerText = auftrag.OrderText
                Node.AppendChild(item)

                Dim item7 As XmlElement = XmlOrders.CreateElement("Gesamtrabatt")
                item7.InnerText = auftrag.Rebate
                Node.AppendChild(item7)

                item7 = XmlOrders.CreateElement("LastEditBy")
                item7.SetAttribute("name", auftrag.LastEditBy.UserName)
                item7.SetAttribute("id", auftrag.LastEditBy.UserID)
                Node.AppendChild(item7)

                If Not String.IsNullOrEmpty(auftrag.TextBefore) Then
                    item = XmlOrders.CreateElement("TextBefore")
                    item.InnerText = auftrag.TextBefore
                    Node.AppendChild(item)
                End If

                If auftrag.PaymentMethode IsNot Nothing Then
                    Dim item3 As XmlElement = XmlOrders.CreateElement("Zahlungsart")
                    item3.InnerText = auftrag.PaymentMethode.Name
                    Node.AppendChild(item3)
                End If

                If auftrag.Reduction.Amount > 0 Then
                    Dim item3 As XmlElement = XmlOrders.CreateElement("FesterAbzug")
                    item3.InnerText = auftrag.Reduction.Amount
                    Node.AppendChild(item3)
                End If

                If String.IsNullOrEmpty(auftrag.ReductionText) = False Then
                    Dim item3 As XmlElement = XmlOrders.CreateElement("FesterAbzugText")
                    item3.InnerText = auftrag.ReductionText
                    Node.AppendChild(item3)
                End If

                CheckAddOrderSetting(Node, "LinkedToInvoice", auftrag.LinkedToInvoice)
                CheckAddOrderSetting(Node, "LinkedFromInvoice", auftrag.LinkedFromInvoice)

                CheckAddOrderSetting(Node, "LinkedToDelivery", auftrag.LinkedToDelivery)
                CheckAddOrderSetting(Node, "LinkedFromDelivery", auftrag.LinkedFromDelivery)

                CheckAddOrderSetting(Node, "LinkedToOffer", auftrag.LinkedToOffer)
                CheckAddOrderSetting(Node, "LinkedFromOffer", auftrag.LinkedFromOffer)

                CheckAddOrderSetting(Node, "LinkedToCredit", auftrag.LinkedToCredit)
                CheckAddOrderSetting(Node, "LinkedFromCredit", auftrag.LinkedFromCredit)

                '##### Kundendaten #####
                'Entweder per Kundennummer oder die komplette Adresse (für nicht Bestandskunden)

                Dim nodekunde As XmlElement
                nodekunde = XmlOrders.CreateElement("Kunde")

                If auftrag.Customer.CustomerID = Nothing Then
                    With auftrag.Customer
                        '#### Kundenadresse noch eintragen
                        Dim kundennummer, anrede, vorname, nachname, titel, strasse, no, plz, ort, land, adresszusatz As XmlElement
                        kundennummer = XmlOrders.CreateElement("Kundennummer")
                        kundennummer.InnerText = Nothing

                        anrede = XmlOrders.CreateElement("Anrede")
                        anrede.InnerText = .Address.Salutation

                        vorname = XmlOrders.CreateElement("Vorname")
                        vorname.InnerText = .Address.Forname

                        nachname = XmlOrders.CreateElement("Nachname")
                        nachname.InnerText = .Address.Surname

                        titel = XmlOrders.CreateElement("Titel")
                        titel.InnerText = .Address.Title

                        strasse = XmlOrders.CreateElement("Strasse")
                        strasse.InnerText = .Address.Street

                        no = XmlOrders.CreateElement("Hausnummer")
                        no.InnerText = .Address.No

                        plz = XmlOrders.CreateElement("PLZ")
                        plz.InnerText = .Address.ZipCode

                        ort = XmlOrders.CreateElement("Ort")
                        ort.InnerText = .Address.City

                        land = XmlOrders.CreateElement("Land")
                        land.InnerText = .Address.Country

                        adresszusatz = XmlOrders.CreateElement("Adresszusatz")
                        adresszusatz.InnerText = .Address.Addition

                        nodekunde.AppendChild(kundennummer)
                        nodekunde.AppendChild(anrede)
                        nodekunde.AppendChild(vorname)
                        nodekunde.AppendChild(nachname)
                        nodekunde.AppendChild(titel)
                        nodekunde.AppendChild(strasse)
                        nodekunde.AppendChild(no)
                        nodekunde.AppendChild(plz)
                        nodekunde.AppendChild(ort)
                        nodekunde.AppendChild(land)
                        nodekunde.AppendChild(adresszusatz)
                    End With

                Else
                    Dim kundennummer As XmlElement
                    kundennummer = XmlOrders.CreateElement("Kundennummer")
                    kundennummer.InnerText = auftrag.Customer.CustomerID
                    nodekunde.AppendChild(kundennummer)
                End If

                If auftrag.DeliveryAddress IsNot Nothing Then
                    With auftrag.DeliveryAddress
                        Try
                            Node.Item("DeliveryAddress").Item("Salutation").InnerText = .Salutation : Node.Item("DeliveryAddress").Item("Forname").InnerText = .Forname
                            Node.Item("DeliveryAddress").Item("Surname").InnerText = .Surname : Node.Item("DeliveryAddress").Item("Addition").InnerText = .Addition
                            Node.Item("DeliveryAddress").Item("Street").InnerText = .Street : Node.Item("DeliveryAddress").Item("No").InnerText = .No
                            Node.Item("DeliveryAddress").Item("Zip").InnerText = .ZipCode : Node.Item("DeliveryAddress").Item("City").InnerText = .City
                            Node.Item("DeliveryAddress").Item("Country").InnerText = .Country
                        Catch ex As Exception
                            'Node existiert noch nicht
                            Dim itemdeliveryaddress As XmlElement = XmlOrders.CreateElement("DeliveryAddress")
                            Dim item2 As XmlElement = XmlOrders.CreateElement("Salutation") : item2.InnerText = .Salutation : itemdeliveryaddress.AppendChild(item2)
                            item2 = XmlOrders.CreateElement("Forname") : item2.InnerText = .Forname : itemdeliveryaddress.AppendChild(item2)
                            item2 = XmlOrders.CreateElement("Surname") : item2.InnerText = .Surname : itemdeliveryaddress.AppendChild(item2)
                            item2 = XmlOrders.CreateElement("Addition") : item2.InnerText = .Addition : itemdeliveryaddress.AppendChild(item2)
                            item2 = XmlOrders.CreateElement("Street") : item2.InnerText = .Street : itemdeliveryaddress.AppendChild(item2)
                            item2 = XmlOrders.CreateElement("No") : item2.InnerText = .No : itemdeliveryaddress.AppendChild(item2)
                            item2 = XmlOrders.CreateElement("Zip") : item2.InnerText = .ZipCode : itemdeliveryaddress.AppendChild(item2)
                            item2 = XmlOrders.CreateElement("City") : item2.InnerText = .City : itemdeliveryaddress.AppendChild(item2)
                            item2 = XmlOrders.CreateElement("Country") : item2.InnerText = .Country : itemdeliveryaddress.AppendChild(item2)
                            Node.AppendChild(itemdeliveryaddress)
                        End Try
                    End With
                End If

                '##### Auftragspositionen #####'
                Dim nodepositionen As XmlElement
                nodepositionen = XmlOrders.CreateElement("Auftragspositionen")
                For Each art As OrderedArticle In auftrag.OrderedArticles
                    Dim root2 As XmlElement
                    root2 = XmlOrders.CreateElement("Artikel")
                    Dim item1, item2, item21, item3, item4, item5, item6 As XmlElement
                    item1 = XmlOrders.CreateElement("Artikelnummer") : item1.InnerText = art.ArticleID
                    item2 = XmlOrders.CreateElement("Auftragspreis") : item2.InnerText = art.OrderPrice.Amount.ToString
                    item21 = XmlOrders.CreateElement("AuftragspreisTyp") : item21.InnerText = Math.Abs(CInt(art.OrderPrice.IsGross))
                    item3 = XmlOrders.CreateElement("Auftragsmenge") : item3.InnerText = art.OrderedAmount.ToString
                    item4 = XmlOrders.CreateElement("Auftragsrabatt") : item4.InnerText = art.OrderRebate.ToString
                    item5 = XmlOrders.CreateElement("Auftragstext") : item5.InnerText = art.OrderText
                    item6 = XmlOrders.CreateElement("PositionsNummer") : item6.InnerText = art.OrderPosition
                    root2.AppendChild(item1) : root2.AppendChild(item2) : root2.AppendChild(item21) : root2.AppendChild(item3) : root2.AppendChild(item4) : root2.AppendChild(item5) : root2.AppendChild(item6)
                    nodepositionen.AppendChild(root2)
                Next

                Node.AppendChild(nodekunde)
                Node.AppendChild(nodepositionen)

                'Nach dem Hauptschlüssel suchen
                Dim Root As Xml.XmlNode = XmlOrders.DocumentElement.SelectSingleNode("/Auftragsliste")
                If Not Root Is Nothing Then
                    Root.AppendChild(Node)
                Else : End If
            End If
            Try
                XmlOrders.Save(auftragsliste)
            Catch : End Try
        Catch : End Try
    End Sub

    Public Sub DeleteOrder(ByVal AuftragsNummer As String, ByVal Dokumenttyp As Dokumentart, usr As User) Implements IDatabase.DeleteOrder
        Try
            If usr.CanWriteOrder = False Then
                RaiseEvent UserRightsMissing(User.OrderWriteDenied)
                Exit Sub
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.OrderWriteDenied)
            Exit Sub
        End Try

        Dim xpath As String = "/Auftragsliste/Auftrag[@LaufendeNr=""{0}"" and @Dokumenttyp=""{1}""]"
        Dim aufnr As String = AuftragsNummer
        Dim typ As String = Dokumenttyp
        xpath = String.Format(xpath, aufnr, typ)
        Dim item As XmlElement = CType(XmlOrders.DocumentElement.SelectSingleNode(xpath), Xml.XmlElement)
        If item IsNot Nothing Then
            Dim element As XmlElement = item.ParentNode
            element.RemoveChild(item)
            XmlOrders.Save(auftragsliste)
        End If
    End Sub
#End Region

#Region "Kunden"
    ''' <summary>
    ''' Gibt einen bestimmten Kunden unter der überführten Kundennummer zurück
    ''' </summary>
    ''' <param name="KundenNummer">Die Kundennummer des gesuchten Kunden</param>
    ''' <returns>Gibt ein Objekt des Typs Kunde zurück</returns>
    ''' <remarks></remarks>
    Public Function GetCustomer(ByVal KundenNummer As String, usr As User) As Customer Implements IDatabase.GetCustomer
        Try
            If usr.CanReadCustomer = False Then
                RaiseEvent UserRightsMissing(User.CustomerReadDenied)
                Return Nothing
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.CustomerReadDenied)
            Return Nothing
        End Try

        Dim temp As Customer
        Try
            'Den Schlüssel finden
            Dim Node As Xml.XmlElement = CType(xdkunden.DocumentElement.SelectSingleNode("/Kundenliste/Kunde[@KundenNr=""" & KundenNummer & """]"), Xml.XmlElement)
            If Not Node Is Nothing Then
                temp = ReadKundenDaten(Node)
            End If
        Catch : End Try
        Return temp
    End Function

    Private Function ReadKundenDaten(ByVal item As XmlElement) As Customer
        Dim temp As New Customer()
        With temp
            .SetKundenNummer(item.Attributes.ItemOf("KundenNr").InnerText)
            .Address.Salutation = item.Item("Anrede").InnerText
            .Address.Title = item.Item("Titel").InnerText
            .Address.Forname = item.Item("Vorname").InnerText
            .Address.Surname = item.Item("Nachname").InnerText
            .Address.Addition = item.Item("Adresszusatz").InnerText
            .Address.No = item.Item("Hausnummer").InnerText
            .Address.Country = item.Item("Land").InnerText
            .Address.ZipCode = item.Item("PLZ").InnerText
            .Address.City = item.Item("Ort").InnerText
            .Address.Street = item.Item("Strasse").InnerText
            If item.Item("CompanyName") IsNot Nothing Then
                .Address.CompanyName = item.Item("CompanyName").InnerText
            End If
            .Preisgruppe = CType([Enum].Parse(GetType(Preisgruppe), item.Item("Preisgruppe").InnerText), Preisgruppe)
            .Contact.Facebook = item.Item("Facebook").InnerText
            .Contact.Mail1 = item.Item("Mail1").InnerText
            .Contact.Mail2 = item.Item("Mail2").InnerText
            .Contact.Mobil1 = item.Item("Mobil1").InnerText
            .Contact.Mobil2 = item.Item("Mobil2").InnerText
            .Contact.Telefax1 = item.Item("Telefax1").InnerText
            .Contact.Telefax2 = item.Item("Telefax2").InnerText
            .Contact.Telefon1 = item.Item("Telefon1").InnerText
            .Contact.Telefon2 = item.Item("Telefon2").InnerText
            .Contact.Twitter = item.Item("Twitter").InnerText
            .Contact.Website = item.Item("Website").InnerText
            If item.Item("IsCompany") IsNot Nothing Then
                .IsCompany = CBool(item.Item("IsCompany").InnerText)
            End If
            If item.Item("Addresses") IsNot Nothing Then
                For Each i As XmlElement In item.Item("Addresses").ChildNodes
                    Dim temp2 As New EAddress
                    temp2.AddressDescription = i.GetAttribute("description")
                    temp2.Salutation = i.Item("Anrede").InnerText
                    temp2.Title = i.Item("Titel").InnerText
                    temp2.Forname = i.Item("Vorname").InnerText
                    temp2.Surname = i.Item("Nachname").InnerText
                    temp2.Addition = i.Item("Adresszusatz").InnerText
                    temp2.No = i.Item("Hausnummer").InnerText
                    temp2.Country = i.Item("Land").InnerText
                    temp2.ZipCode = i.Item("PLZ").InnerText
                    temp2.City = i.Item("Ort").InnerText
                    temp2.Street = i.Item("Strasse").InnerText
                    If i.Item("CompanyName") IsNot Nothing Then
                        temp2.CompanyName = i.Item("CompanyName").InnerText
                    End If
                    .Addresses.Add(temp2)
                Next
            End If

            If item.Item("Bezahlmethode") IsNot Nothing Then
                .PaymentMethode = PaymentMethode.GetByName(item.Item("Bezahlmethode").InnerText, Me)
            Else
                .PaymentMethode = New PaymentMethode
            End If
        End With
        Return temp
    End Function

    Public Function GetAllCustomers(usr As User) As IList(Of CustomerPreviewModel) Implements IDatabase.GetAllCustomers
        Try
            If usr.CanReadCustomer = False Then
                RaiseEvent UserRightsMissing(User.CustomerReadDenied)
                Return New ObservableCollection(Of CustomerPreviewModel)
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.CustomerReadDenied)
            Return New ObservableCollection(Of CustomerPreviewModel)
        End Try
        Dim returnlist As New ObservableCollection(Of CustomerPreviewModel)
        Dim xmllist As New Collection(Of XmlElement)
        Dim mutex As New Mutex
        Dim root As XmlElement = xdkunden.DocumentElement
        Dim nodeList As XmlNodeList = root.GetElementsByTagName("Kunde")

        Dim list As IEnumerator = nodeList.GetEnumerator
        Dim kundenliste As New Collection(Of XmlElement)
        Do While (list.MoveNext())
            xmllist.Add(list.Current)
        Loop
        Parallel.ForEach(xmllist, Sub(item)
                                      Dim temp As Customer = ReadKundenDaten(item)
                                      mutex.WaitOne()
                                      returnlist.Add(New CustomerPreviewModel With {.Address = temp.Address.ToString, .CustomerID = temp.CustomerID, .DisplayedName = temp.DisplayName})
                                      mutex.ReleaseMutex()
                                  End Sub)
        Return returnlist
    End Function

    ''' <summary>
    ''' Prüft, ob ein Kunde unter der übergebenen Kundennummer angelegt ist.
    ''' </summary>
    ''' <param name="Kundennummer">Zu überprüfende Kundennummer</param>
    ''' <returns>True falls ein Kunde unter dieser Nummer schon existiert</returns>
    ''' <remarks></remarks>
    Public Function ExistsCustomer(ByVal Kundennummer As String, usr As User) As Boolean Implements IDatabase.CustomerExists
        Try
            If usr.CanReadCustomer = False Then
                RaiseEvent UserRightsMissing(User.CustomerReadDenied)
                Return False
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.CustomerReadDenied)
            Return False
        End Try
        Try
            'Den Schlüssel finden
            Dim Node As Xml.XmlElement = CType(xdkunden.DocumentElement.SelectSingleNode("/Kundenliste/Kunde[@KundenNr=""" & Kundennummer & """]"), Xml.XmlElement)
            If Not Node Is Nothing Then
                Return True
            Else
                Return False
            End If
        Catch
            Return False
        End Try
    End Function

    ''' <summary>
    ''' Speichert den eingegebenen Kunden in der Datenbank ab
    ''' </summary>
    ''' <param name="Customer">Objekt des Typs Kunde</param>
    ''' <remarks></remarks>
    Public Sub SetCustomer(ByVal Customer As Customer, usr As User) Implements IDatabase.SaveOrUpdateCustomer
        Try
            If usr.CanWriteCustomer = False Then
                RaiseEvent UserRightsMissing(User.CustomerWriteDenied)
                Exit Sub
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.CustomerWriteDenied)
            Exit Sub
        End Try
        Try
            'Den Schlüssel finden
            Dim Node As Xml.XmlElement = CType(xdkunden.DocumentElement.SelectSingleNode("/Kundenliste/Kunde[@KundenNr=""" & Customer.CustomerID & """]"), Xml.XmlElement)
            If Not Node Is Nothing Then
                'Schlüssel gefunden, Änderung vornehmen
                With Customer
                    Node.Item("Anrede").InnerText = .Address.Salutation
                    Node.Item("Vorname").InnerText = .Address.Forname
                    Node.Item("Nachname").InnerText = .Address.Surname
                    Node.Item("Titel").InnerText = .Address.Title
                    Node.Item("Strasse").InnerText = .Address.Street
                    Node.Item("Hausnummer").InnerText = .Address.No
                    Node.Item("PLZ").InnerText = .Address.ZipCode
                    Node.Item("Ort").InnerText = .Address.City
                    Node.Item("Land").InnerText = .Address.Country
                    Node.Item("Adresszusatz").InnerText = .Address.Addition

                    Node.Item("Preisgruppe").InnerText = .Preisgruppe

                    Node.Item("Facebook").InnerText = .Contact.Facebook
                    Node.Item("Mail1").InnerText = .Contact.Mail1
                    Node.Item("Mail2").InnerText = .Contact.Mail2
                    Node.Item("Mobil1").InnerText = .Contact.Mobil1
                    Node.Item("Mobil2").InnerText = .Contact.Mobil2
                    Node.Item("Telefax1").InnerText = .Contact.Telefax1
                    Node.Item("Telefax2").InnerText = .Contact.Telefax2
                    Node.Item("Telefon1").InnerText = .Contact.Telefon1
                    Node.Item("Telefon2").InnerText = .Contact.Telefon2
                    Node.Item("Twitter").InnerText = .Contact.Twitter
                    Node.Item("Website").InnerText = .Contact.Website

                    If String.IsNullOrEmpty(.Address.CompanyName) = False Then
                        If Node.Item("CompanyName") IsNot Nothing Then
                            Node.Item("CompanyName").InnerText = .Address.CompanyName
                        Else
                            Dim item = xdkunden.CreateElement("CompanyName") : item.InnerText = .Address.CompanyName : Node.AppendChild(item)
                        End If
                    End If

                    If .PaymentMethode IsNot Nothing Then
                        If Node.Item("Bezahlmethode") IsNot Nothing Then
                            Node.Item("Bezahlmethode").InnerText = .PaymentMethode.Name
                        Else
                            Dim item = xdkunden.CreateElement("Bezahlmethode") : item.InnerText = .PaymentMethode.Name : Node.AppendChild(item)
                        End If
                    End If

                    If .IsCompany = True Then
                        If Node.Item("IsCompany") IsNot Nothing Then
                            Node.Item("IsCompany").InnerText = .IsCompany
                        Else
                            Dim item = xdkunden.CreateElement("IsCompany") : item.InnerText = .IsCompany : Node.AppendChild(item)
                        End If
                    End If

                    If .Addresses.Count = 0 Then
                        'Adressen löschen
                        If Node.Item("Addresses") IsNot Nothing Then
                            Node.RemoveChild(Node.Item("Addresses"))
                        End If
                    Else
                        'Adressen aktualisieren
                        'Löschen, um neu anzulegen
                        If Node.Item("Addresses") IsNot Nothing Then
                            Node.RemoveChild(Node.Item("Addresses"))
                        End If
                        Dim item As XmlElement = xdkunden.CreateElement("Addresses")
                        For Each a As EAddress In .Addresses
                            Dim temp As XmlElement = xdkunden.CreateElement("Address") : temp.SetAttribute("description", a.AddressDescription)

                            Dim anrede, vorname, nachname, titel, strasse, no, plz, ort, land, adresszusatz As XmlElement
                            anrede = xdkunden.CreateElement("Anrede") : anrede.InnerText = a.Salutation
                            vorname = xdkunden.CreateElement("Vorname") : vorname.InnerText = a.Forname
                            nachname = xdkunden.CreateElement("Nachname") : nachname.InnerText = a.Surname
                            titel = xdkunden.CreateElement("Titel") : titel.InnerText = a.Title
                            strasse = xdkunden.CreateElement("Strasse") : strasse.InnerText = a.Street
                            no = xdkunden.CreateElement("Hausnummer") : no.InnerText = a.No
                            plz = xdkunden.CreateElement("PLZ") : plz.InnerText = a.ZipCode
                            ort = xdkunden.CreateElement("Ort") : ort.InnerText = a.City
                            land = xdkunden.CreateElement("Land") : land.InnerText = a.Country
                            adresszusatz = xdkunden.CreateElement("Adresszusatz") : adresszusatz.InnerText = a.Addition
                            If String.IsNullOrEmpty(a.CompanyName) = False Then
                                Dim item2 = xdkunden.CreateElement("CompanyName") : item2.InnerText = a.CompanyName : temp.AppendChild(item2)
                            End If

                            temp.AppendChild(anrede) : temp.AppendChild(vorname) : temp.AppendChild(nachname) : temp.AppendChild(titel) : temp.AppendChild(strasse)
                            temp.AppendChild(no) : temp.AppendChild(plz) : temp.AppendChild(ort) : temp.AppendChild(land) : temp.AppendChild(adresszusatz)

                            item.AppendChild(temp)
                        Next
                        Node.AppendChild(item)
                    End If
                End With

            Else
                'Schlüssel nicht gefunden, neu erstellen
                Node = xdkunden.CreateElement("Kunde")
                Node.SetAttribute("KundenNr", Customer.CustomerID)

                '##### Kundendaten #####
                With Customer
                    Dim anrede, vorname, nachname, titel, strasse, no, plz, ort, land, adresszusatz As XmlElement
                    anrede = xdkunden.CreateElement("Anrede") : anrede.InnerText = .Address.Salutation
                    vorname = xdkunden.CreateElement("Vorname") : vorname.InnerText = .Address.Forname
                    nachname = xdkunden.CreateElement("Nachname") : nachname.InnerText = .Address.Surname
                    titel = xdkunden.CreateElement("Titel") : titel.InnerText = .Address.Title
                    strasse = xdkunden.CreateElement("Strasse") : strasse.InnerText = .Address.Street
                    no = xdkunden.CreateElement("Hausnummer") : no.InnerText = .Address.No
                    plz = xdkunden.CreateElement("PLZ") : plz.InnerText = .Address.ZipCode
                    ort = xdkunden.CreateElement("Ort") : ort.InnerText = .Address.City
                    land = xdkunden.CreateElement("Land") : land.InnerText = .Address.Country
                    adresszusatz = xdkunden.CreateElement("Adresszusatz") : adresszusatz.InnerText = .Address.Addition

                    Node.AppendChild(anrede) : Node.AppendChild(vorname) : Node.AppendChild(nachname) : Node.AppendChild(titel) : Node.AppendChild(strasse) : Node.AppendChild(no)
                    Node.AppendChild(plz) : Node.AppendChild(ort) : Node.AppendChild(land) : Node.AppendChild(adresszusatz)

                    Dim item = xdkunden.CreateElement("Facebook") : item.InnerText = .Contact.Facebook : Node.AppendChild(item)
                    item = xdkunden.CreateElement("Mail1") : item.InnerText = .Contact.Mail1 : Node.AppendChild(item)
                    item = xdkunden.CreateElement("Mail2") : item.InnerText = .Contact.Mail2 : Node.AppendChild(item)
                    item = xdkunden.CreateElement("Mobil1") : item.InnerText = .Contact.Mobil1 : Node.AppendChild(item)
                    item = xdkunden.CreateElement("Mobil2") : item.InnerText = .Contact.Mobil2 : Node.AppendChild(item)
                    item = xdkunden.CreateElement("Telefax1") : item.InnerText = .Contact.Telefax1 : Node.AppendChild(item)
                    item = xdkunden.CreateElement("Telefax2") : item.InnerText = .Contact.Telefax2 : Node.AppendChild(item)
                    item = xdkunden.CreateElement("Telefon1") : item.InnerText = .Contact.Telefon1 : Node.AppendChild(item)
                    item = xdkunden.CreateElement("Telefon2") : item.InnerText = .Contact.Telefon2 : Node.AppendChild(item)
                    item = xdkunden.CreateElement("Twitter") : item.InnerText = .Contact.Twitter : Node.AppendChild(item)
                    item = xdkunden.CreateElement("Website") : item.InnerText = .Contact.Website : Node.AppendChild(item)
                    item = xdkunden.CreateElement("Preisgruppe") : item.InnerText = .Preisgruppe : Node.AppendChild(item)
                    If String.IsNullOrEmpty(.Address.CompanyName) = False Then
                        item = xdkunden.CreateElement("CompanyName") : item.InnerText = .Address.CompanyName : Node.AppendChild(item)
                    End If

                    If .IsCompany = True Then
                        If Node.Item("IsCompany") IsNot Nothing Then
                            Node.Item("IsCompany").InnerText = .IsCompany
                        Else
                            item = xdkunden.CreateElement("IsCompany") : item.InnerText = .IsCompany : Node.AppendChild(item)
                        End If
                    End If

                    If .Addresses.Count > 0 Then
                        'For Each a As EAddress In .Addresses
                        item = xdkunden.CreateElement("Addresses")
                        For Each a As EAddress In .Addresses
                            Dim temp = xdkunden.CreateElement("Address") : temp.SetAttribute("description", a.AddressDescription)
                            anrede = xdkunden.CreateElement("Anrede") : anrede.InnerText = a.Salutation
                            vorname = xdkunden.CreateElement("Vorname") : vorname.InnerText = a.Forname
                            nachname = xdkunden.CreateElement("Nachname") : nachname.InnerText = a.Surname
                            titel = xdkunden.CreateElement("Titel") : titel.InnerText = a.Title
                            strasse = xdkunden.CreateElement("Strasse") : strasse.InnerText = a.Street
                            no = xdkunden.CreateElement("Hausnummer") : no.InnerText = a.No
                            plz = xdkunden.CreateElement("PLZ") : plz.InnerText = a.ZipCode
                            ort = xdkunden.CreateElement("Ort") : ort.InnerText = a.City
                            land = xdkunden.CreateElement("Land") : land.InnerText = a.Country
                            adresszusatz = xdkunden.CreateElement("Adresszusatz") : adresszusatz.InnerText = a.Addition
                            If String.IsNullOrEmpty(a.CompanyName) = False Then
                                Dim item2 = xdkunden.CreateElement("CompanyName") : item2.InnerText = a.CompanyName : temp.AppendChild(item2)
                            End If

                            temp.AppendChild(anrede) : temp.AppendChild(vorname) : temp.AppendChild(nachname) : temp.AppendChild(titel) : temp.AppendChild(strasse)
                            temp.AppendChild(no) : temp.AppendChild(plz) : temp.AppendChild(ort) : temp.AppendChild(land) : temp.AppendChild(adresszusatz)

                            item.AppendChild(temp)
                        Next
                        Node.AppendChild(item)
                        'Next
                    End If

                    If .PaymentMethode IsNot Nothing Then
                        item = xdkunden.CreateElement("Bezahlmethode")
                        item.InnerText = .PaymentMethode.Name
                        Node.AppendChild(item)
                    End If
                End With

                'Nach dem Hauptschlüssel suchen
                Dim Root As Xml.XmlNode = xdkunden.DocumentElement.SelectSingleNode("/Kundenliste")
                If Not Root Is Nothing Then
                    Root.AppendChild(Node)
                Else
                End If
            End If
            Try
                xdkunden.Save(kundenliste)
            Catch : End Try
        Catch : End Try
    End Sub

    Public Sub DeleteCustomer(ByVal CustomerID As String, usr As User) Implements IDatabase.DeleteCustomer
        Try
            If usr.CanWriteCustomer = False Then
                RaiseEvent UserRightsMissing(User.CustomerWriteDenied)
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.CustomerWriteDenied)
        End Try
        Dim xpath As String = "/Kundenliste/Kunde[@KundenNr=""{0}""]"
        Dim artnr As String = CustomerID
        xpath = String.Format(xpath, artnr)
        Dim item As XmlElement = CType(xdkunden.DocumentElement.SelectSingleNode(xpath), Xml.XmlElement)
        If item IsNot Nothing Then
            Dim element As XmlElement = item.ParentNode
            element.RemoveChild(item)
            xdkunden.Save(kundenliste)
        End If
    End Sub
#End Region

#Region "Artikelkategorien"
    Private items As TreeViewItem
    Public Sub SetKategorie(ByVal cat As Category, usr As User) Implements IDatabase.SetCategory
        Try
            If usr.CanWriteArticle = False Then
                RaiseEvent UserRightsMissing(User.ArticleWriteDenied)
                Exit Sub
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.ArticleWriteDenied)
            Exit Sub
        End Try

        Try
            Dim depth As Integer = 0
            Dim plist As New List(Of String)
            Dim path As String = ""
            Dim tcat As Category = cat
            While tcat.Parent IsNot Nothing
                tcat = tcat.Parent
                depth += 1
                plist.Add("/Category[@Name=""" & tcat.Name & """]")
            End While

            plist.Reverse()
            For Each item In plist
                path += item
            Next

            'get the value
            Dim Node As XmlElement
            Node = xdkategorien.CreateElement("Category")
            Node.SetAttribute("Name", cat.Name)
            'Node.SetAttribute("Depth", depth.ToString)

            If cat.DefaultTax IsNot Nothing Then
                Dim item As XmlElement = xdkategorien.CreateElement("StandardTax")
                item.InnerText = cat.DefaultTax.Name
                Node.AppendChild(item)
            End If

            Dim Root As Xml.XmlNode = xdkategorien.DocumentElement.SelectSingleNode("/Kategorieliste" + path)
            If Not Root Is Nothing Then
                Root.AppendChild(Node)
            End If
        Catch
        End Try
        xdkategorien.Save(kategorieliste)
    End Sub

    Private Function GetAllKategoriesfromNodeList(ByVal nodeList As IEnumerable(Of XmlElement), depth As Integer, Optional ByVal AsTreeViewItem As Boolean = False) As Object
        Dim list As IEnumerator = nodeList.GetEnumerator

        Dim collection As New Collection(Of Category)

        Do While (list.MoveNext())
            Dim item As XmlElement
            item = CType(list.Current, XmlElement)
            Dim cat As New Category()
            cat.Name = item.GetAttribute("Name")
            Try
                cat.DefaultTax = TaxClass.GetByName(item.Item("StandardTax").InnerText, Me)
            Catch ex As Exception

            End Try
            Dim newnodelist = From childnodes As XmlElement In item.ChildNodes Where childnodes.Name = "Category"

            Dim ncolkat As Collection(Of Category) = GetAllKategoriesfromNodeList(newnodelist, depth + 1)
            If ncolkat.Count > 0 Then
                For Each child As Category In ncolkat
                    child.Parent = cat
                    cat.Children.Add(child)
                Next
            End If
            collection.Add(cat)
        Loop
        Return collection
    End Function

    Public Function CategoryExists(Key As String, usr As User) As Boolean Implements IDatabase.CategoryExists
        Try
            If usr.CanReadArticle = False Then
                RaiseEvent UserRightsMissing(User.ArticleReadDenied)
                Return True
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.ArticleReadDenied)
            Return True
        End Try

        Dim root = xdkategorien.DocumentElement.SelectNodes("//Category[@Name=""" + Key + """]")
        If root.Count = 0 Then
            Return False
        Else : Return True
        End If
    End Function

    Public Function GetCategories(ByVal MainKey As String, usr As User) As Category Implements IDatabase.GetCategories
        Try
            If usr.CanReadArticle = False Then
                RaiseEvent UserRightsMissing(User.ArticleReadDenied)
                Return Nothing
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.ArticleReadDenied)
            Return Nothing
        End Try

        Dim main As New Category
        Dim temp As New Collection(Of Category)
        Dim root As XmlElement = xdkategorien.DocumentElement.SelectSingleNode("/Kategorieliste")
        Dim nodeList As XmlNodeList = root.ChildNodes
        Dim list As IEnumerator = nodeList.GetEnumerator
        Do While (list.MoveNext())
            Dim item = CType(list.Current, XmlElement)
            If item.GetAttribute("Name") = MainKey Then
                main.Name = MainKey
                If item.Item("StandardTax") IsNot Nothing Then
                    main.DefaultTax = TaxClass.GetByName(item.Item("StandardTax").InnerText, Me)
                End If

                'Neues root element setzen, um unterkategorien zu bekommen
                Dim root2 As XmlElement = item
                Dim nodelist2 = From childnodes2 As XmlElement In root2.ChildNodes Where childnodes2.Name = "Category"
                Dim childnodes As Collection(Of Category) = GetAllKategoriesfromNodeList(nodelist2, 1)

                If childnodes.Count > 0 Then
                    For Each cat As Category In childnodes
                        cat.Parent = main
                        main.Children.Add(cat)
                    Next
                End If
            End If
        Loop
        Return main
    End Function

    Public Sub DeleteCategory(cat As Category, usr As User) Implements IDatabase.DeleteCategory
        Try
            If usr.CanWriteArticle = False Then
                RaiseEvent UserRightsMissing(User.ArticleWriteDenied)
                Exit Sub
            End If
        Catch ex As Exception
            RaiseEvent UserRightsMissing(User.ArticleWriteDenied)
            Exit Sub
        End Try

        Dim plist As New List(Of String)
        Dim path As String = ""
        Dim tcat As Category = cat
        plist.Add("/Category[@Name=""" & tcat.Name & """]")
        While tcat.Parent IsNot Nothing
            tcat = tcat.Parent
            plist.Add("/Category[@Name=""" & tcat.Name & """]")
        End While
        plist.Reverse()
        For Each item As String In plist
            path += item
        Next
        Dim item2 As XmlElement = CType(xdkategorien.DocumentElement.SelectSingleNode("/Kategorieliste" + path), Xml.XmlElement)
        If item2 IsNot Nothing Then
            Dim element As XmlElement = item2.ParentNode
            element.RemoveChild(item2)
            xdkategorien.Save(kategorieliste)
        End If
    End Sub
#End Region

#Region "Temp Files"
    ''' <summary>
    ''' Methode to save open orders, costumers and articles to load them on the next programm start
    ''' </summary>
    ''' <param name="Orders">The open orders</param>
    ''' <param name="Customers">The open orders</param>
    ''' <param name="Articles"></param>
    ''' <remarks></remarks>
    Public Sub SaveTemps(ByVal Orders As IList(Of Order), ByVal Customers As IList(Of Customer), ByVal Articles As IList(Of Article), usr As User) Implements IDatabase.SaveTemps
        Try
            If usr.CanWriteDatabase = False Then
                'Throw New MissingPermissionException("FastXML", User.DatabaseWriteDenied)
                Exit Sub
            End If
        Catch ex As Exception
            'Throw New MissingPermissionException("FastXML", User.DatabaseWriteDenied)
            Exit Sub
        End Try
        Dim node As XmlElement
        For Each auf As Order In Orders
            node = xdtemp.CreateElement("Auftrag")
            node.SetAttribute("LaufendeNr", auf.OrderID.ToString)
            node.SetAttribute("Dokumenttyp", auf.DokumentArt)

            'Nach dem Hauptschlüssel suchen
            Dim Root As Xml.XmlNode = xdtemp.DocumentElement.SelectSingleNode("/Temp")
            If Not Root Is Nothing Then
                Root.AppendChild(node)
            Else : End If
            SetOrder(auf, usr)
        Next
        xdtemp.Save(temp)
    End Sub

    Public Function LoadTempOrders(usr As User) As IList(Of Order) Implements IDatabase.LoadTempOrders
        Try
            If usr.CanReadDatabase = False Then
                'Throw New MissingPermissionException("FastXML", User.DatabaseReadDenied)
                Exit Function
            End If
        Catch ex As Exception
            'Throw New MissingPermissionException("FastXML", User.DatabaseWriteDenied)
            Exit Function
        End Try
        Dim mutex As New Mutex
        Dim root As XmlElement = xdtemp.DocumentElement
        Dim nodeList As XmlNodeList = root.GetElementsByTagName("Auftrag")
        Dim list As IEnumerator = nodeList.GetEnumerator

        Dim collection As New Collection(Of XmlElement)
        Dim rlist As New ObservableCollection(Of Order)
        Do While list.MoveNext
            collection.Add(list.Current)
        Loop

        Parallel.ForEach(collection, Sub(item As XmlElement)
                                         Dim auftrag As Order = GetOrder(item.Attributes.GetNamedItem("LaufendeNr").Value, item.Attributes.GetNamedItem("Dokumenttyp").Value, usr)
                                         mutex.WaitOne()
                                         rlist.Add(auftrag)
                                         mutex.ReleaseMutex()
                                     End Sub)
        For Each item As XmlElement In collection
            xdtemp.DocumentElement.RemoveChild(item)
        Next
        xdtemp.Save(temp)

        Return rlist
    End Function

    Public Function LoadTempArticle(usr As User) As IList(Of Article) Implements IDatabase.LoadTempArticle
        Return Nothing
    End Function

    Public Function LoadTempCustomer(usr As User) As IList(Of Customer) Implements IDatabase.LoadTempCustomer
        Return Nothing
    End Function
#End Region

    Public Function Backup() As String Implements IDatabase.Backup
        ' Configure open file dialog box
        Dim dlg As New System.Windows.Forms.SaveFileDialog()
        dlg.Title = "Sicherung speichern"
        dlg.DefaultExt = ".zip" ' Default file extension
        dlg.Filter = "Zip-Archiv |*.zip" ' Filter files by extension
        dlg.FileName = "Sicherung " + Datum.Today
        If dlg.ShowDialog() = Windows.Forms.DialogResult.OK Then
            Dim _backup As New BackupAndRestore(_directory + "Firma")
            Dim t1 As New Thread(Sub()
                                     _backup.Backup(dlg.FileName)
                                 End Sub)
            t1.Start()
            t1.Join()
            Return (dlg.FileName)
        End If
        Return Nothing
    End Function

    Public Function Restore() As Boolean Implements IDatabase.Restore
        Dim dlg As New System.Windows.Forms.OpenFileDialog()
        dlg.Title = "Sicherung wiederherstellen"
        dlg.DefaultExt = ".zip" ' Default file extension
        dlg.Filter = "Zip-Archiv |*.zip" ' Filter files by extension
        If dlg.ShowDialog() = Windows.Forms.DialogResult.OK Then
            Try
                Dim backup As New BackupAndRestore(_directory + "Firma")
                Dim t1 As New Thread(Sub()
                                         backup.Wiederherstellen(dlg.FileName)
                                     End Sub)
                t1.Start()
                t1.Join()
                Return True
            Catch ex As Exception : End Try
        End If
        Return False
    End Function

    Public Event DatabaseError(message As String) Implements IDatabase.DatabaseError
    Public Event UserRightsMissing(message As String) Implements IDatabase.UserRightsMissing

#Region "Users"
    Public Function GetUser(username As String) As nHibernate.Models.UserPreviewModel Implements IDatabase.GetUser
        Dim path As String = _directory + "\Firma\Users.xml"
        Dim doc As XElement
        If IO.File.Exists(path) = False Then
            doc = New XElement("Users")
            doc.Save(path)
        End If
        doc = XElement.Load(path)
        Dim output = New nHibernate.Models.UserPreviewModel

        Try
            Dim userlist = (From users In doc.Descendants("User") Where users.Attribute("name") = username).SingleOrDefault
            With output
                .UserName = username
                .UserID = userlist.Attribute("id").Value
                .Hash = userlist.Attribute("hash").Value
                .CanEditUsers = userlist.Attribute("cu").Value

                .CanReadArticle = userlist.Attribute("cra").Value
                .CanWriteArticle = userlist.Attribute("cwa").Value

                .CanReadCustomer = userlist.Attribute("crc").Value
                .CanWriteCustomer = userlist.Attribute("cwc").Value

                .CanReadOrder = userlist.Attribute("cro").Value
                .CanWriteOrder = userlist.Attribute("cwo").Value

                .CanReadDatabase = userlist.Attribute("crd").Value
                .CanWriteDatabase = userlist.Attribute("cwd").Value
            End With
        Catch ex As Exception
            Log.AddError(ex.InnerException.ToString + " -> FastXML -> GetUser")
        End Try
        Return output
    End Function

    Public Sub SaveOrUpdateUser(user As nHibernate.Models.UserPreviewModel, _currentuser As User) Implements IDatabase.SaveOrUpdateUser
        If _currentuser Is Nothing AndAlso GetAllUsers.Count > 0 Then
            Try
                If Not _currentuser.CanEditUsers AndAlso GetAllUsers.Count = 0 Then
                    RaiseEvent UserRightsMissing("Es kann kein Benutzer angelegt werden, da bereits Benutzer angelegt wurden und keine Rechte existieren.")
                    Exit Sub
                End If
            Catch ex As Exception
                Log.AddError(ex.ToString)
                RaiseEvent UserRightsMissing(ex.ToString)
                Exit Sub
            End Try
        End If
        Dim path As String = _directory + "\Firma\Users.xml"
        Dim doc As New XElement("User")
        doc.SetAttributeValue("name", user.UserName)
        doc.SetAttributeValue("cro", user.CanReadOrder)
        doc.SetAttributeValue("cwo", user.CanWriteOrder)
        doc.SetAttributeValue("cra", user.CanReadArticle)
        doc.SetAttributeValue("cwa", user.CanWriteArticle)
        doc.SetAttributeValue("crc", user.CanReadCustomer)
        doc.SetAttributeValue("cwc", user.CanWriteCustomer)
        doc.SetAttributeValue("crd", user.CanReadDatabase)
        doc.SetAttributeValue("cwd", user.CanWriteDatabase)
        doc.SetAttributeValue("cu", user.CanEditUsers)
        doc.SetAttributeValue("id", user.UserID)
        doc.SetAttributeValue("hash", user.Hash)
        Dim root As XElement = XElement.Load(path)
        Dim userlist = From users In root.Descendants("User") Where users.Attribute("name").Value = user.UserName
        Try
            If userlist.Count = 0 Then
                root.Add(doc)
                root.Save(path)
            Else
                root.Descendants("User").Where(Function(x) x.Attribute("name").Value = user.UserName).Remove()
                root.Add(doc)
                root.Save(path)
            End If
        Catch ex As Exception
            Log.AddError(ex.InnerException.ToString + " -> FastXML -> SaveOrUpdateUser")
        End Try
    End Sub

    Public Function UserExists(username As String) As Boolean Implements IDatabase.UserExists
        Try
            Dim path As String = _directory + "\Firma\Users.xml"
            Dim root As XElement = XElement.Load(path)
            Dim userlist = From users In root.Descendants("User") Where users.Attribute("name").Value = username
            If userlist.Count = 0 Then
                Return False
            Else
                Return True
            End If
        Catch ex As Exception
            Log.AddError(ex.InnerException.ToString + " -> FastXML -> UserExists")
            Return True
        End Try
    End Function

    Public Function UserIDExists(userID As String) As Boolean Implements IDatabase.UserIDExists
        Try
            Dim path As String = _directory + "\Firma\Users.xml"
            Dim root As XElement = XElement.Load(path)
            Dim userlist = From users In root.Descendants("User") Where users.Attribute("id").Value = userID
            If userlist.Count = 0 Then
                Return False
            Else
                Return True
            End If
        Catch ex As Exception
            Log.AddError(ex.InnerException.ToString + " -> FastXML -> UserIDExists")
            Return True
        End Try
    End Function

    Public Function GetAllUsers() As IList(Of nHibernate.Models.UserPreviewModel) Implements IDatabase.GetAllUsers
        Dim l As New List(Of nHibernate.Models.UserPreviewModel)
        Dim path As String = _directory + "\Firma\Users.xml"
        Try
            Dim doc As XElement '= XElement.Load(path)
            If IO.File.Exists(path) = False Then
                doc = New XElement("Users")
                doc.Save(path)
            End If
            doc = XElement.Load(path)
            Dim _userlist = From users In doc.Descendants("User")
            For Each item In _userlist
                Dim u As New nHibernate.Models.UserPreviewModel()
                With u
                    .UserName = item.Attribute("name")
                    .UserID = item.Attribute("id")
                    .CanReadOrder = item.Attribute("cro").Value
                    .CanWriteOrder = item.Attribute("cwo").Value
                    .CanReadArticle = item.Attribute("cra").Value
                    .CanWriteArticle = item.Attribute("cwa").Value
                    .CanReadCustomer = item.Attribute("crc").Value
                    .CanWriteCustomer = item.Attribute("cwc").Value
                    .CanReadDatabase = item.Attribute("crd").Value
                    .CanWriteDatabase = item.Attribute("cwd").Value
                    .CanEditUsers = item.Attribute("cu").Value
                End With
                l.Add(u)
            Next
        Catch ex As Exception
            'File not found. For example on firstrun
        End Try

        Return l
    End Function
#End Region

    Public ReadOnly Property SupportsTemporaryItems As Boolean Implements IDatabase.SupportsTemporaryItems
        Get
            Return True
        End Get
    End Property

    Public ReadOnly Property SupportsBackupAndRestore As Boolean Implements IDatabase.SupportsBackupAndRestore
        Get
            Return True
        End Get
    End Property

    Public Function CheckChangedArticles() As IList(Of nHibernate.Models.ArticleModel) Implements IDatabase.CheckChangedArticles

    End Function

    Public Function CheckChangedCustomers() As IList(Of nHibernate.Models.CustomerModel) Implements IDatabase.CheckChangedCustomers

    End Function

    Public Function CheckChangedOrders() As IList(Of nHibernate.Models.OrderModel) Implements IDatabase.CheckChangedOrders

    End Function

    Public ReadOnly Property SupportsSyncing As Boolean Implements IDatabase.SupportsSyncing
        Get
            Return False
        End Get
    End Property

    Public Sub SaveObject(Of T)(key As String, appid As String, obj As T)

    End Sub

    Private Function GetObject(Of T)(key As String, appid As String) As T

    End Function

    Public Shared Function Serialize(Of T)(value As T) As String
        If value Is Nothing Then
            Return Nothing
        End If

        Dim serializer As New XmlSerializer(GetType(T))
        Dim settings As New XmlWriterSettings()
        settings.Encoding = New UnicodeEncoding(False, False)
        settings.Indent = False
        settings.OmitXmlDeclaration = False

        Using textWriter As New StringWriter()
            Using xmlWriter1 As XmlWriter = XmlWriter.Create(textWriter, settings)
                serializer.Serialize(xmlWriter1, value)
            End Using
            Return textWriter.ToString()
        End Using
    End Function

    Public Shared Function Deserialize(Of T)(xml As String) As T
        If String.IsNullOrEmpty(xml) Then
            Return Nothing
        End If

        Dim serializer As New XmlSerializer(GetType(T))
        Dim settings As New XmlReaderSettings()

        Using textReader As New StringReader(xml)
            Using xmlReader1 As XmlReader = XmlReader.Create(textReader, settings)
                Return DirectCast(serializer.Deserialize(xmlReader1), T)
            End Using
        End Using
    End Function
End Class
